Dynamic Namespaces Socket.IO

后端 未结 5 606
再見小時候
再見小時候 2021-01-30 09:32

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\

5条回答
  •  北荒
    北荒 (楼主)
    2021-01-30 10:03

    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.

    • Best way to do dynamic routing with Express.js (node.js)
    • Using routes in Express-js
    • http://expressjs.com/api.html#app.routes
    • http://shtylman.com/post/expressjs-re-routing/
    • http://jordanhoff.com/post/22602013678/dynamic-express-routing

    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()
    
    // : 
    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!

提交回复
热议问题