2015-04-23 92 views
3

我想知道如何在一个名称空间中共享套接字中设置的数据并在另一个名称空间上访问它?Socket.io在名称空间之间共享套接字数据

我完全知道我可以将数据附加到套接字对象本身。当我将数据附加到一个名称空间并尝试在另一个名称空间上访问它时,会出现问题。

下面说明问题

var io = require('socket.io'); 

module.exports.init = function(server) { 

    io = io.listen(server); 

    io.of('/chatSystem').on('connection', function(socket) { 
     /*handling set nickname event*/ 
     socket.on('set.name', function(data) { 
      /*attach nickname key to this socket*/ 
      socket.nickname = data.name; 
      socket.broadcast.emit('user.entered', data); 
     }); 
    }); 

    io.of('/chatUser').on('connection', function(socket) { 
     /*handling client event socket.send*/ 
     socket.on('message', function(data) { 
      data = JSON.parse(data); 
      data.nickname = socket.nickname; // <--- this is undefined 

      /*send to all connected client(broadcast will not send message to socket that created the message)*/ 
      socket.broadcast.send(JSON.stringify(data)); 
      data.type = 'myMessage'; 

      /*manually send back the message to the socket that created the message*/ 
      socket.send(JSON.stringify(data)); 
     }); 
    }); 
}; 

是有办法解决这一问题?

+1

我面临同样的问题。当试图在另一个命名空间中读取时,在一个名称命名空间中设置的名称未定义。 如果所有的消息都只使用一个套接字'io.on('connection',function(){.....})'这个工作正常。但不能使用两个不同的名称空间。 –

+0

我面临同样的问题,并希望对此有一个答案。 –

回答

1

更新我的回答更通用的和“更安全”的解决方案

事实证明,我们可以跨命名空间共享数据,但我们必须从一次提到的Socket实例做命名空间到另一个。

假设有两个命名空间,即namespace_Anamespace_B

要从内namespace_B得到namepsace_A相应插座对象,我们取它通过在使用当前插座对象的ID(因为这将是相似的)从连接对象namespace_A命名空间对象。

虽然这仍然是一种解决方法,但这是迄今为止我能够在名称空间之间共享会话数据的最好和最安全的方式。

我们将使用socket.id来引用所需的套接字。 这些ID看起来像这样:/namespace#vCpuzzUi4RI1DHqfAAAH。 名称空间内的每个套接字实例的ID都相似,但名称空间部分(即,即,对于namespace_A,ID将类似于/namespace_A#vCpuzzUi4RI1DHqfAAAH,对于命名空间_B将是/namespace_B#vCpuzzUi4RI1DHqfAAAH。因此,如果我们可以生成类似于当前套接字的套接字ID并使用它,我们可以在另一个名称空间中引用一个套接字实例。

,我们需要做的是首先声明一个变量在一开始喜欢什么:

var self = this; 

这是用来抱到本对象的引用。一个命名空间中 接下来,假设namespace_A,我们在写这个代码需要从namespace_B的Socket实例数据:

ns_b_socket = self.namespace_B.connected['/namespace_B#' + buildSocketID(socket.id)]; 

我们使用self.namespace_B,然后调用指本实例的namespace_B连接。连接

命名空间#:对象连接到该命名空间由 ID索引的Socket对象

哈希。

我使用自定义函数来生成ID。现在

function buildSocketID(iden) { 
    return iden.split('#')[1]; 
} 

,如果从namespace_Ans_b_socket.username,你会得到namespace_Bsocket.username设置的值。

注意:这适用于版本1.0.x及以上。对于低于此的版本,请参阅here

2

这可能有点晚,但我只是偶然找到一个更简单的解决方案,并认为我会分享给未来的调查人员。

套接字> 1.0,则可以将共享数据存储在套接字的客户端对象中。它似乎依然插座

之间共享使用上述

/* attach nickname key to this socket */ 
    socket.client.nickname = data.name; 
    /* In typescript with @types/socket.io */ 
    socket.client["nickname"] = data.name; 

和检索

data.nickname = socket.client.nickname; 
    /* In typescript with @types/socket.io */ 
    data.name = socket.client["nickname"]; 

希望你们的榜样这可以帮助别人了。我一直试图找到一个解决方案,并在这个线程偶然发现。一小时后,我找到了这个选择。

0

嗨我想到了一个workround。观看

var io = require('socket.io'); 

module.exports.init =函数(服务器){

/** 
    * Hi This is where things, get tricky now. 
    * statement of Problem: Am trying to send message between two namespaces. 
    * first made individual namespace socket global, 
    * And create a function that will utilized these global sockets as their second arguments 
    * and make calls to them 
    */ 

io = io.listen(server); 
var chatSystemPresentSocket; // making it Global 
var chatUserPresentSocket; //making it Global 

io.of('/chatSystem').on('connection', function(socket) { 
    /*handling set nickname event*/ 
    socket.on('set.name', function(data) { 
     /*attach nickname key to this socket*/ 
     //socket Global for the moment. 
     chatSystemPresentSocket = socket; 

     sendtochatSystem(data) // function calls 
     socket.nickname = data.name; 
     socket.broadcast.emit('user.entered', data); 
    }); 
}); 

io.of('/chatUser').on('connection', function(socket) { 
    /*handling client event socket.send*/ 
    socket.on('message', function(data) { 
     /* make socket global for the moment.*/ 
     chatUserPresentSocket = socket; 
     sendtochatSystem(data); 
     data = JSON.parse(data); 
     data.nickname = socket.nickname; // <--- this is undefined 

     /*send to all connected client(broadcast will not send message to socket that created the message)*/ 
     socket.broadcast.send(JSON.stringify(data)); 
     data.type = 'myMessage'; 

     /*manually send back the message to the socket that created the message*/ 
     socket.send(JSON.stringify(data)); 
    }); 
}); 

//Make a function to use one of the global sockets of one of the namespaces 
function sendToChatUser(data, chatUserPresentSocket){ 
chatUserPresentSocket.emit('your event', data) 
} 

function sendToChatSystem(data, chatSystemPresentSocket){ 
chatSystemPresentSocket.emit('your event', data) 
} 

};

测试一下,如果它不适合您,请在我的代码中编辑