How can I use dynamic namespaces in socket.io.
I'm looking in the (poor) documentation, and it says that namespaces must be used like this:
io.of('/news')
io.of('/akfda')
To use a namespace you do io.of("/namespace").
Do I need to register every single namespace in the server? Maybe I want a namespace for dynamic content.
How can I do something like :
io.of('/:somethign/:id')
Socket.IO supports 'rooms' (https://github.com/LearnBoost/socket.io/wiki/Rooms), you can use it instead of namespaces. Also when you need dynamic in routes (and you using express in your app) - best way is to use use route-engine from express box.
However, if you still think that you need dynamic in namespaces in socket.io, here is small example how it can be implemented:
User-side:
var connect = function (ns) {
    return io.connect(ns, {
       query: 'ns='+ns,
       resource: "socket.io"
    });
}
var socket = connect('/user/12');
Server-side:
var url = require('url');
  , ev = new events.EventEmitter()
// <ns name>: <ns regexp>
var routes = {
  // /user/:id
  'user': '^\\/user\\/(\\d+)$',
  // /:something/:id
  'default': '^\\/(\\\w+)\\/(\\d+)$'
};
// global entry point for new connections
io.sockets.on('connection', function (socket) {
  // extract namespace from connected url query param 'ns'
  var ns = url.parse(socket.handshake.url, true).query.ns;
  console.log('connected ns: '+ns)
  //
  for (var k in routes) {
    var routeName = k;
    var routeRegexp = new RegExp(routes[k]);
    // if connected ns matched with route regexp
    if (ns.match(routeRegexp)) {
      console.log('matched: '+routeName)
      // create new namespace (or use previously created)
      io.of(ns).on('connection', function (socket) {
        // fire event when socket connecting
        ev.emit('socket.connection route.'+routeName, socket);
        // @todo: add more if needed
        // on('message') -> ev.emit(...)
      });
      break;
    }
  }
  // when nothing matched
  // ...
});
// event when socket connected in 'user' namespace
ev.on('socket.connection route.user', function () {
  console.log('route[user] connecting..');
});
// event when socket connected in 'default' namespace
ev.on('socket.connection route.default', function () {
  console.log('route[default] connecting..');
});
I hope this will help you!
I would use "rooms" to support your dynamic content.
Server Side
var server = require('http').createServer(),
    io     = require('socket.io')(server);
io.on('connection', function(socket){
  var room = socket.handshake['query']['r_var'];
  socket.join(room);
  console.log('user joined room #'+room);
  socket.on('disconnect', function() {
    socket.leave(room)
    console.log('user disconnected');
  });
  socket.on('chat message', function(msg){
    io.to(room).emit('chat message', msg);
  });
});
server.listen(3000);
Client Side
var socket_connect = function (room) {
    return io('localhost:3000', {
        query: 'r_var='+room
    });
}
var random_room = Math.floor((Math.random() * 2) + 1);
var socket      = socket_connect(random_room);
socket.emit('chat message', 'hello room #'+random_room);
....
                        As of version 2.1.1 I was able to make it work with this:
wss.of((nsp, query, next) => {
  const { token } = query;
  // Do your authentication or whatever here...
  // If success
  next(null, true);
}).on('connect', (socket) => {
  // socket connected to your namespace
});
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With