How to store client associated data in socket.io 1.0
Asked Answered
S

2

22

The docs say socket.io doesn't support .get .set now

Is it okay to store client associated data like

io.sockets.on('connection', function (client) {
    client.on('data', function (somedata) {            
        client['data'] = somedata;
    });    
});

in case I need multiple nodes?

Schedule answered 29/4, 2015 at 3:45 Comment(1)
What is the variable client? You're missing a bunch of context here for anyone to be able to answer.Winkelman
W
29

Yes, it is OK to add properties to the socket.io socket object. You should be careful to not use names that could conflict with built-in properties or methods (I'd suggest adding a leading underscore or namescoping them with some sort of name prefix). But a socket is just a Javascript object and you're free to add properties like this to it as long as you don't cause any conflict with existing properties.

There are other ways to do this that use the socket.id as a key into your own data structure.

var currentConnections = {};
io.sockets.on('connection', function (client) {
    currentConnections[client.id] = {socket: client};
    client.on('data', function (somedata) {  
        currentConnections[client.id].data = someData; 
    });    
    client.on('disconnect', function() {
        delete currentConnections[client.id];
    });
});
Winkelman answered 29/4, 2015 at 4:5 Comment(10)
is this info available to the client to see / mutate ?Thies
@Thies - No. Data like what is in the curentConnections object is server-side data and is private to the server.Winkelman
sorry meant if i were to attach data to the socket obj if its mutable to the client. Now that i see what you did. i had a duh momentThies
@Thies - The socket obj here is local to the server. Any properties you put on it are not available to the client in any way. This is true client/server. The only thing a client sees is something the server explicitly sends to it. socket.io doesn't do any magical syncing of socket properties between client and server.Winkelman
In my case this currentSessions object is coming as undefined at the time of accessing socketidZoosporangium
@Tripathi29 - If you want help with your specific code, you will have to post your own question and show your own code. We can't help when we can't see the code you have.Winkelman
@Winkelman how about a similar scenario with clustering/ multiple nodes? Basically for a local variable to be shared across multiple nodes/child threads, I found suggestions like extending the socket-io.redis adapter to store each addition to socket or adapter object, but is there any more cleaner solution?Jabalpur
@JeetKumar - To share something so it is available to multiple processes, you would usually use something like redis to store it centrally where all processes can access it. So, you can either use a new central redis store (or something similar) or you can extend socket-io.redis adapter.Winkelman
@Winkelman hi! I am having difficulty understanding this syntax currentConnections[client.id] = {socket: client};Bernabernadene
@Bernabernadene - currentConnections is an object I declared (you can see it in my code). client.id is the socket.io id value (unique for each connection). I use that as a property value on the currentConnections object and I store in that property another object that I can put as many properties on it as I want. Here, I just show {socket: client}; but one could add many more properties for that socket there as in {socket: client, socketColor: "blue", connectionStartTime: Date.now()}; and so on. Then, at any time, when given a socket or socket id, you can look up any of those properties.Winkelman
M
16

Yes, that's possible as long as there is no other builtin properties with same name.

io.sockets.on('connection', function (client) {
    client.on('data', function (somedata) {  
        // if not client['data']  you might need to have a check here like this
        client['data'] = somedata;
    });    
});

I'd suggest another way, but with ECMAScript 6 weak maps

var wm = new WeakMap();

io.sockets.on('connection', function (client) {
    client.on('data', function (somedata) {   
        wm.set(client, somedata);
        // if you want to get the data
        // wm.get(client);
    }); 
    client.on('disconnect', function() {
        wm.delete(client);
    });   
});
Meister answered 29/4, 2015 at 4:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.