I want to know how to share data being set in a socket in one namespace and access it on another namespace?
I'm fully aware that i can attach data to the socket object itself.Problem arise when i attach the data on one namespace and try to access it on another namespace.
Below demonstrate the problem
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) );
});
});
};
Is there a way to fix this?
I want to know how to share data being set in a socket in one namespace and access it on another namespace?
I'm fully aware that i can attach data to the socket object itself.Problem arise when i attach the data on one namespace and try to access it on another namespace.
Below demonstrate the problem
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) );
});
});
};
Is there a way to fix this?
Share Improve this question asked Apr 23, 2015 at 13:01 slierslier 6,7506 gold badges41 silver badges57 bronze badges 2-
1
I am facing the same problem. Name set in one name namespace is found undefined when tried to fetch in another namespace. If all the messages are sent using only one socket
io.on('connection', function() {.....})
this works fine. But not with two different namespaces. – Mandar Pandit Commented May 16, 2015 at 4:42 - I am facing the same problem and would like to have an answer to this. – Sajib Acharya Commented Jan 23, 2016 at 15:12
3 Answers
Reset to default 4This might be a bit late but i just stumbled on a simpler solution and thought i would share for future investigators.
with socket > 1.0, you can store shared data in the socket's client object. It seems to still be shared among sockets
to use your example above
/* attach nickname key to this socket */
socket.client.nickname = data.name;
/* In typescript with @types/socket.io */
socket.client["nickname"] = data.name;
and for retrieval
data.nickname = socket.client.nickname;
/* In typescript with @types/socket.io */
data.name = socket.client["nickname"];
Hope this helps someone out. I have been trying to find a solution all week and stumbled on this thread. An hour later, I found this alternative.
UPDATING MY ANSWER FOR A MORE GENERIC AND "SAFER" SOLUTION
It turns out that we could share data across namespaces, but we have to do that by referring the socket instance from once namespace to another.
Suppose there are two namespaces, namely, namespace_A and namespace_B.
To get the corresponding socket object on namepsace_A from within namespace_B, we fetch it by using the current socket object's ID (as it will be similar) from the connected object in the namespace_A namespace object.
Though this is still kind of an workaround, but this is by far the best and safest way I have been able to share session data among namespaces.
We'll use the socket.id to refer to the required sockets.
The IDs look something like this: /namespace#vCpuzzUi4RI1DHqfAAAH
.
Each socket instance within the namespaces have the IDs similar except for the namespace portion, i. e., for namespace_A, the ID would be something like /namespace_A#vCpuzzUi4RI1DHqfAAAH
and for namespace_B it would be /namespace_B#vCpuzzUi4RI1DHqfAAAH
. Therefore we could refer one socket instance from one namespace in another if we could generate a socket ID similar to the present socket and use it.
What we need to do is first declare a variable at the beginning like:
var self = this;
This is used to hold a reference to the present object. Next within one namespace, suppose namespace_A, we need data from socket instance of namespace_B by writing this code in A:
ns_b_socket = self.namespace_B.connected['/namespace_B#' + buildSocketID(socket.id)];
We refer to the namespace_B of the present instance using self.namespace_B
and then call connected over it.
Namespace#connected:Object
Hash of Socket objects that are connected to this namespace indexed by id.
I use a custom function to generate the ID.
function buildSocketID(iden) {
return iden.split('#')[1];
}
Now, if you call ns_b_socket.username
from namespace_A
, you'd get the value set for socket.username
from namespace_B.
NOTE: This works for version 1.0.x and above. For version below this, refer here.
Hi I thought of a workround. watch
var io = require( 'socket.io' );
module.exports.init = function( server ) {
/**
* 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)
}
};
Test it, if it doesnt fit in you know, where to edit in my code