Javascript 动态名称空间Socket.IO

Javascript 动态名称空间Socket.IO,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,如何在socket.io中使用动态名称空间 我在看(穷人),它说名称空间必须像这样使用: io.of('/news') io.of('/akfda') 要使用名称空间,请执行(“/namespace”)的io.of 我需要注册服务器中的每个名称空间吗?也许我想要一个动态内容的名称空间 我怎样才能做到: io.of('/:something/:id')Socket.io支持“房间”(rooms)),您可以使用它而不是名称空间。此外,当您需要动态路线(并且您在应用程序中使用express)时,最好的

如何在socket.io中使用动态名称空间

我在看(穷人),它说名称空间必须像这样使用:

io.of('/news')

io.of('/akfda')

要使用名称空间,请执行(“/namespace”)的io.of

我需要注册服务器中的每个名称空间吗?也许我想要一个动态内容的名称空间

我怎样才能做到:


io.of('/:something/:id')
Socket.io支持“房间”(rooms)),您可以使用它而不是名称空间。此外,当您需要动态路线(并且您在应用程序中使用express)时,最好的方法是使用express box中的路线引擎

但是,如果您仍然认为socket.io中的名称空间需要动态,下面是一个如何实现它的小示例:

用户端:

var connect = function (ns) {
    return io.connect(ns, {
       query: 'ns='+ns,
       resource: "socket.io"
    });
}

var socket = connect('/user/12');
服务器端:

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..');
});
var url=require('url');
,ev=新事件。EventEmitter()
// : 
变量路由={
///user/:id
“用户”:“^\\/user\\/(\\d+)$”,
///:某物/:id
“默认值”:“^\\/(\\\w+)\\/(\\d+)$”
};
//新连接的全局入口点
io.sockets.on('connection',函数(socket){
//从连接的url查询参数“ns”提取命名空间
var ns=url.parse(socket.handshake.url,true);
console.log('已连接的ns:'+ns)
//
for(路由中的var k){
var-routeName=k;
var routeRegexp=new RegExp(routes[k]);
//如果连接的ns与路由regexp匹配
if(ns.match(routeRegexp)){
console.log('matched:'+routeName)
//创建新名称空间(或使用以前创建的名称空间)
io.of(ns).on('connection',function(socket)){
//插座连接时发生火灾事件
ev.emit('socket.connection route.'+routeName,socket');
//@todo:如果需要,请添加更多
//on('message')->ev.emit(…)
});
打破
}
}
//当没有匹配的时候
// ...
});
//在“用户”命名空间中连接套接字时发生的事件
ev.on('socket.connection route.user',函数(){
log('路由[用户]连接..');
});
//在“默认”命名空间中连接套接字时发生的事件
ev.on('socket.connection route.default',函数(){
log('路由[默认]连接..');
});

我希望这对你有帮助

这里有一种方法。下面是我为解决此问题而创建的socket.io子类:

该子类添加了动态名称空间以及虚拟主机名支持(如果您愿意,每个主机都可以进入自己的名称空间树)。回购协议有一些例子

下面是一个通用socket.io侦听器,它侦听每个请求的命名空间,并为每个连接的套接字记录一条消息。您可以监听不同的regexp来监听名称空间的任何子集

它与标准socket.io客户端库一起工作,无需任何修改

var DynamicServer = require('dynamic.io'); io = DynamicServer({ host: true, // Enable virtual host handling publicStatus: true // Enable /socket.io/status page. }); // Any number of namespace patterns can be set up. // This is an example of a single catch-all pattern. io.setupNamespace(/.*/, function(nsp) { nsp.on('connect', function(socket) { console.log('a socket connected on', nsp.fullname()); }); nsp.expire(function() { console.log(nsp.fullname(), 'is expiring'); }); }); io.listen(8888); var DynamicServer=require('dynamic.io'); io=动态服务器({ 主机:true,//启用虚拟主机处理 publicStatus:true//Enable/socket.io/status页。 }); //可以设置任意数量的命名空间模式。 //这是一个单一全面模式的示例。 io.setupNamespace(/.*/,函数(nsp){ nsp.on('connect',功能(插座){ log('上连接的套接字',nsp.fullname()); }); nsp.expire(函数(){ log(nsp.fullname(),'is expiring'); }); }); 听(8888); 我会使用“房间”来支持您的动态内容

服务器端

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);
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);
....
客户端

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);
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);
....

服务器

var MAX_CLIENTS = 5;
var namespace_queue = [];

function searchObjectOnArray(nameKey, myArray) {
    for (var i = 0; i < myArray.length; i++) {
        if (myArray[i].id === nameKey) {
            return myArray[i];
        }
    }
}

function createNamespace(data){
    var ns = {
                //id: require('node-uuid')(),
                id : data.name,
                clients: 0, 
            };

    namespace_queue.push(ns);

    return ns;
}

createNamespace({name: 'primer'});

io.of('').on('connection', function(socket){     

    console.log('-' + socket.id);

    /// Welcome to the new client
    socket.emit('Welcome', {SocketId : socket.id});

    socket.on('JoinToApp', function (data, callback) {
        var namespaceToConnect = searchObjectOnArray(data.namespace, namespace_queue)
        if(namespaceToConnect.clients <= MAX_CLIENTS){
            var dynamicNamespace = io.of('/' + namespaceToConnect.id);

            dynamicNamespace.on('connection', function(ns_socket){
                    console.log('user connected to ' + namespaceToConnect.id);
                    dynamicNamespace.emit('hi', 'everyone!');
                });

            namespaceToConnect.clients++;  
        }          

        callback({namespaces:namespace_queue});
    })

    socket.on('createNamespace',function(data,join_cb){

        createNamespace(data);

        join_cb({message:'Namespace created'});
    }); 
});
var MAX_客户=5;
var namespace_queue=[];
函数searchObjectOnArray(nameKey,myArray){
对于(var i=0;i如果(namespaceToConnect.clients从版本
2.1.1
起,我能够使它与此一起工作:

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
});

从阅读文档和谷歌搜索来看,socket.io似乎没有这个功能。请看这里:你能再次解释一下你的示例吗?我正在做同样的事情,我认为这非常有用,但我不明白你是如何做的。我不确定这是什么时候添加的,但现在你可以用你的na的正则表达式来做Messpace name:在与命名空间斗争了几个小时之后,我终于解决了我的房间问题!但是你不能将房间添加到你的房间中。非常有用。谢谢!因为你保持了命名空间名称与命名空间实例的本地映射。当我们将实例从1扩展到n时,这将如何表现。我们可以在中保存nampespace实例吗redis以它的名字命名用于缩放。是的,它在文档中就是这样。但是这些参数(nsp、查询、下一个)从哪里来?我不知道。好的,我想我现在知道了。使用.of()和正则表达式或函数可以使它自动侦听连接到匹配的命名空间名称,然后创建它。。