10

I want to save some data on the socket, server side, so whenever the client emits any data to the server, I want that data to be available!

One use case can be storing a token on the socket. When the client is connecting for the first time, it will emit the token, if it has one, or it will show the login page and then the login data will be sent to the server. Whichever one it is, I want to store the token on the server, so that every request after that doesn't need to specify the token.

Later, I'll use RedisStore, so all the data will be accessible all the servers running the app.

My only question is, where do I store the data on the socket so it's associated with that client?

3 Answers 3

11

on http://socket.io/#how-to-use scroll to: Storing data associated to a client

use socket.set and socket.get to set and get data asynchronously

Sign up to request clarification or add additional context in comments.

3 Comments

That method seems to not work anymore on socket.io 1.0, any possible update?
The io.set() and io.get() methods are deprecated in 1.0. You'll have to use middleware. socket.io/docs/migrating-from-0-9
this link is expired.
2

I'm suffering from the same question and guessing what's going on with an example code from socket.io on version 4.x

In the example, They use middleware(use function to register a middleware)

namespace.use((socket, next) => {
  // get data from client
  const sessionID = socket.handshake.auth.sessionID;
  const {userId, username} = yourFunction();
  // set socket specific data
  socket.sessionID = sessionID;
  socket.userID = session.userID;
  socket.username = session.username;
  next();
});

Middlewares are executed when a socket is connected with a server.

and you can use the data afterward

note - Socket.IO reference tells use socket.data for this purpose

namespace.on('connection', socket => {
    socket.emit("join", `${socket.username} has been joined`);
})

If you use multiple servers, then you have to keep in mind that the data is only valid for the server

On multiple server environment, You need a single source of data which will be used by socket servers.

namespace.use(async (socket: Socket & { sessionID?: string, userID?: string, username?: string }, next) => {
    const sessionID = socket.handshake.auth.sessionID; // [socket.handshake][4]
// or other [socket related attributes][4]
    if (sessionID) {
        // you have to implement a function to save and retrive session info
        const session = await someFunctionToRetrieveSession(sessionID);
        if (session) {
            socket.sessionID = sessionID;
            socket.userID = session.userID;
            socket.username = session.username;
            return next();
        }
    }
    const username = socket.handshake.auth.username;
    if (!username) {
        return next(new Error("invalid username"));
    }
    socket.sessionID = randomId();
    socket.userID = randomId();
    socket.username = username;
    next();
});

and one more thing as I understood the namespace.use function is called only for the namespace if your client use other namespace then default then default('/') use function will not be called.

//client side
io("/chat");
...

//server side
io.use() // == io.of('/').use() will not be called
io.of('/chat').use() // only will be called

Thanksfully the author of the example implemented a sessionStorage using redis refer to this example code

with this info, I guess socket.io server saves sockets' info in memory and set a property of a socket will be saved and when the socket comes later the server retrives the socket and it's related data. but because it happens on memory so you can't share the info among other servers that's why you have to find a way to share the data with other servers(eg. redis)

Comments

-1

You can save the data on the global variables when you dont want to use any database

var globalVariable = {};

io.sockets.on("connection", function (socket) {

    socket.on("save-client-data", function (clientData) {
          var clientId = clientData.clientId;
          globalVariable[clientId] = JSON.parse(clientHandshakeData);
    });

    socket.on("get-client-data", function (clientId) {

          var clientData =  globalVariable[clientId];
          socket.emit("get-client-data", JSON.stringify(clientData));

    });

});

This worked for my scenario, however I'm not aware of the performance implications.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.