29

socket.ioで動的名前空間を使用するにはどうすればよいですか。

私は(貧弱な)ドキュメントを調べていますが、名前空間は次のように使用する必要があると書かれています。

io.of('/news')

io.of('/akfda')

名前空間を使用するには、次のようにしますio.of("/namespace")

サーバーにすべての名前空間を登録する必要がありますか?動的コンテンツの名前空間が必要なのかもしれません。

どうすれば次のようなことができますか:

io.of('/:somethign/:id')

4

5 に答える 5

41

Socket.IOは「部屋」(https://github.com/LearnBoost/socket.io/wiki/Rooms)をサポートしており、名前空間の代わりに使用できます。また、ルートで動的が必要な場合(およびアプリでエクスプレスを使用している場合)-最適な方法は、エクスプレスボックスのroute-engineを使用することです。

ただし、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..');
});

これがお役に立てば幸いです。

于 2013-10-27T13:09:38.360 に答える
21

私はあなたのダイナミックなコンテンツをサポートするために「部屋」を使います。

サーバ側

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);
....
于 2015-04-17T00:21:20.403 に答える
7

バージョンの時点で、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
});
于 2018-11-30T11:20:56.797 に答える
3

サーバ

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

クライアント

<input id="namespaceInput" type="text" placeholder="New namespace name">
<input id="namespaceToConnect" type="text" placeholder="namespace to connect">

<button onclick="javascript: createNamespace()">Create Namespace</button>
<button onclick="javascript: joinToNamespace()">Connect to Namespace</button>

<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
    var socket = null;
   (function(){
       socket = io.connect('http://localhost:3000/');        
   })()

   function createNamespace(){
       var namespaceName = document.getElementById("namespaceInput").value;
       socket.emit('createNamespace', {name : namespaceName}, function(data){
           alert(data.message);
       })
   }

   function joinToNamespace(){
       var name = document.getElementById("namespaceToConnect").value;
       socket.emit('JoinToApp', {namespace: name}, function(data){
            console.log('Namespaces created:');
            console.log(data)

            var ns_socket = io.connect('http://localhost:3000/' + name);
            ns_socket.on('connect',function(){
                console.log('joined namespace ' + name);
            });

            ns_socket.on('hi', function(data){
                console.log('hi ' + data)
            })
        });

   }
</script>

詳細:https ://ingcamilorodriguez.wordpress.com/2016/06/21/como-hacer-namespaces-dinamicos-en-socket-io/

于 2016-06-29T19:39:32.007 に答える
2

これが1つの方法です。問題を解決するために作成したsocket.ioサブクラスは次のとおりです。

https://github.com/PencilCode/dynamic.io

このサブクラスは、動的な名前空間と仮想ホスト名のサポートを追加します(必要に応じて、各ホストは独自の名前空間ツリーに入ることができます)。そのリポジトリにはいくつかの例があります。

これは、要求されたすべての名前空間をリッスンし、接続するすべてのソケットのメッセージをログに記録するユニバーサルsocket.ioリスナーです。別の正規表現をリッスンして、名前空間のサブセットをリッスンすることができます。

これは、変更なしで標準のsocket.ioクライアントライブラリで動作します。

var DynamicServer = require('dynamic.io');
io = DynamicServer({
    host:true、//仮想ホストの処理を有効にする
    publicStatus:true///socket.io/statusページを有効にします。
});
//任意の数の名前空間パターンを設定できます。
//これは単一のキャッチオールパターンの例です。
io.setupNamespace(/.*/、function(nsp){
    nsp.on('connect'、function(socket){
        console.log('接続されたソケット'、nsp.fullname());
    });
    nsp.expire(function(){
        console.log(nsp.fullname()、'期限切れです');
    });
});
io.listen(8888);
于 2014-11-05T17:09:30.727 に答える