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?

Herokiller
  • 2,891
  • 5
  • 32
  • 50

2 Answers2

28

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];
    });
});
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • 2
    is this info available to the client to see / mutate ? – Alex_Nabu Mar 09 '16 at 14:05
  • 1
    @Alex_Nabu - No. Data like what is in the `curentConnections` object is server-side data and is private to the server. – jfriend00 Mar 09 '16 at 15:24
  • 1
    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 moment – Alex_Nabu Mar 09 '16 at 17:09
  • 2
    @Alex_Nabu - 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. – jfriend00 Mar 09 '16 at 17:11
  • In my case this currentSessions object is coming as undefined at the time of accessing socketid – Abhishek Tripathi Jan 09 '17 at 15:10
  • @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. – jfriend00 Jan 09 '17 at 17:54
  • @jfriend00 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? – Jeet Kumar Jul 12 '17 at 13:56
  • @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. – jfriend00 Jul 12 '17 at 15:39
  • @jfriend00 hi! I am having difficulty understanding this syntax ```currentConnections[client.id] = {socket: client};``` – Aedric Nov 14 '19 at 22:17
  • 1
    @Aedric - `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. – jfriend00 Nov 14 '19 at 22:30
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);
    });   
});
code-jaff
  • 9,230
  • 4
  • 35
  • 56