Namespaces

Remember how we set up our original websocket server? For that take a look at the following code:

// [snip]

// Connect the websocket handler to our server
var websocket = require('socket.io')(server);
// Create a handler for incoming websocket connections
websocket.on('UserConnectedEvent', function (socket) {
  console.log("New user connected");
  // Tell others a new user connected
  socket.broadcast.emit('UserConnectedEvent', null);
  // Bind event handler for incoming messages
  socket.on('MessageSentEvent', function (chatData) {
    console.log('Received new chat message');
    // By using the 'broadcast' connector, we will
    // send the message to everyone except the sender.
    socket.broadcast.emit('MessageReceivedEvent', chatData);
  });
});

Here, we simply used the main socket.io instance in order to directly register socket connections and their respective callbacks. However, looking a little closer, what we actually did was connect all the incoming connections to a namespace, even if this happened implicitly. Take a look at the following snippet from the preceding code:

websocket.on('UserConnectedEvent', function (socket) {
  console.log("New user connected");
  // Tell others a new user connected
  socket.broadcast.emit('UserConnectedEvent', null);
  // Bind event handler for incoming messages
  socket.on('MessageSentEvent', function (chatData) {
    console.log('Received new chat message');
    // By using the 'broadcast' connector, we will
    // send the message to everyone except the sender.
    socket.broadcast.emit('MessageReceivedEvent', chatData);
  });

What is actually happening here is that we are registering the connections on the root namespace (written as /), which is the one namespace that socket.io gives us to work with even if we specify no other namespaces. This goes to show that namespaces are actually essential for the way socket.io works internally. In fact, every single connection that you have going will be associated with a single namespace, even if it is an implicit one!

Your users connect to the root namespace whenever they connect directly to the URL of your WebSocket server. For example, they can do this by doing the following on the client side:

var socket = io.connect('http://localhost:8080');

You are in effect telling socket.io that you wish to establish a connection to the root namespace.

The problem is that if we perform the preceding steps (as we have done until now), all the messages that we send to the server are open for broadcasting to all the other connected clients as well (this happens even if you have other namespaces defined, as we will see later). This is not very convenient if we want to concentrate on communications.

Let's say that we want to divide communications in order to let users subscribe to websocket channels, which sends information that interests them. For example, let's say that we are building a chat application that will let them speak about various programming languages such as Java, Scala, and JavaScript. In that case, we can define namespaces on the server side by doing the following:

websocket.of('/java').on('UserConnectedEvent', function (socket) {
  console.log("New user connected to the Java channel");
  socket.broadcast.emit('UserConnectedEvent', null);
  socket.on('MessageSentEvent', function (chatData) {
    console.log('Received new Java chat message');
    socket.broadcast.emit('MessageReceivedEvent', chatData);
});

websocket.of('/scala').on('UserConnectedEvent', function (socket) {
  console.log("New user connected to the Scala channel");
  socket.broadcast.emit('UserConnectedEvent', null);
  socket.on('MessageSentEvent', function (chatData) {
    console.log('Received new Scala chat message');
    socket.broadcast.emit('MessageReceivedEvent', chatData);
});

websocket.of('/javascript').on('UserConnectedEvent', function (socket) {
  console.log("New user connected to the Java channel");
  socket.broadcast.emit('UserConnectedEvent', null);
  socket.on('MessageSentEvent', function (chatData) {
    console.log('Received new Javascript chat message');
    socket.broadcast.emit('MessageReceivedEvent', chatData);
});

The important parts of the code are emphasized. Note how we use the of function in order to create the actual namespace. The argument of the function is the name of the namespace relative to the root namespace (/).

After the namespace is created, we register socket connections in a way that is familiar to us by now after having (albeit unknowingly!) done the same thing with the root namespace earlier.

We can now make use of these modifications to the server by having the client connect to any given namespace available. For example, for the ones that we have already defined here, you can connect to each of them like this (respectively):

var javaSocket = io.connect('http://localhost:8080/java');

var scalaSocket = io.connect('http://localhost:8080/scala');

var javascriptSocket = io.connect('http://localhost:8080/javascript');

Then, proceed to operate on them just as you would in the case of any other single WebSocket connection, as follows:

javaSocket.on('UserConnectedEvent', function (user) {
  console.log('User connected to the Java channel:', user);
});

This is all pretty straightforward, as you will note as you dig in a little deeper. Let's do so by dusting off the simple chat application that we wrote in the last chapter and giving it some genuine namespacing love.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.44.53