Broadcasting with channels
Channels are an abstraction that make it easy to broadcast events to many clients at once.
When a client first connects, you register its session to one or many channels and from then-on any events broadcast on those channels will also be sent to that client.
Don’t worry about deregistering the session from the channel; that is automatically handled for you when the session disconnects, but you can also do it manually if you no longer wish to listen for events on a channel at any time.
Channels can be used for things such as notification systems, chat rooms and synchronizing data between multiple clients.
Create a channel
We are going to be making a channel that does two things:
- Synchronizes a number with all clients that counts up every second, and,
- Sends a count tracking how many users are online in real time.
Let’s start off from where the Getting Started guide finished as a base:
Right now we have a simple mechanism where a client connects and receives an event with the data "Hello world!"
.
This is nice, but what if we want to say hi to everyone at once? Or in a more real-world example, send live updates about real-time events in our system to select groups of our users? This is where we can use channels.
To make a channel, you simply need to call the exported createChannel
factory function.
Let’s create a channel called ticker in a new file and export it:
Then import the channel to where your route handler is located and register the session so that it can start receiving events:
New sessions will now be subscribed to your channel and will start receiving its events!
Channels are powerful in that you can register your session to listen on many channels at once or none at all. This makes it dynamically configurable based on what channels your client may or may not be authorized to receive events from and allows you to have a lot of flexibility in your implementation.
Make a synchronized counter
Now that you have a channel and your sessions are registered with it, lets actually make it do something.
We are going to have a number that increments by one (1) every second and synchronize it across all of our connected clients in real time.
Right after your create your channel, add the following:
Here we have a variable count
that gets incremented by 1
every 1000ms (one second).
We then broadcast the value of count
on the ticker
channel every interval under the event name tick
which will be received by all of our registered sessions.
Back on our client-side let’s write some code that updates a text field on the page with the received value:
In this snippet the following is happening:
- We create a
pre
element stored in a variablecountElement
and add it to our document body. - We create an
EventSource
to listen to events from our server. - We listen for the
tick
event and, when received, set the text incountElement
to display the received value, corresponding to thecount
variable on the server.
Open it up in your browser (you can run the pre-made example project if you haven’t been following along) and you will now see your ticking counter being updated in real time!
You can open the same page in multiple tabs at once and notice that the value is kept in sync across them all. Easy!
Track online users
Let’s add some more functionality to our ticker
channel. This time we want to keep our users in the know about how many other users are on the site at the same time as them. No one wants to feel lonely!
Channels emit events when certain things happen such as sessions being registered, deregistered and being disconnected. Let’s listen on these events to broadcast the total number of connected sessions at any given time.
Add the following code after where you create the channel:
Here we create a function broadcastSessionCount
that broadcasts a value with the current total session count exposed to us under the Channel sessionCount
property with the event name session-count
.
We then listen on both the events session-registered
and session-deregistered
and set the broadcastSessionCount
function as a callback for each. This way, every time a session joins or leaves the channel the count is re-broadcasted and updated for all of the existing sessions on the channel.
Back on our client lets add another listener for our new event that displays the session count in another text field:
We do a similar thing to our previous example:
- Create a
pre
element stored in a variablesessionsElement
and add it to our document body. - Listen for the
session-count
event and, when received, set the text insessionsElement
to display the received value, corresponding to the number of active sessions connected.
Once again open the page in your browser (or run the example project) and you will now see a new text element with a real-time updating display of the active sessions. Open and close more tabs on the same page and observe how the count changes to stay in sync. Amazing!