socket.io Get data io.sockets.clients(); Not working anymore

Tags: , ,



This was working fine before, why did they remove it? Before you can create objects with user properties on frontend and assign it to the socket.user property for each connection using a code like this ex below in the backend.

socket.on("new_visitor", user => {
    console.log("new_visitor", user);
    socket.user = user;
    emitVisitors();
});

then retrieve all these data through the sockets object eg.

 const getVisitors = () => {
     let clients = io.sockets.clients().connected;
     let sockets = Object.values(clients);
     let users = sockets.map(s => s.user);
     return users;
 };

//frontend
  componentWillMount() {
    axios.get('http://geoplugin.net/json.gp').then(res => {
      const {
        geoplugin_request,
        geoplugin_countryCode,
        geoplugin_city,
        geoplugin_region,
        geoplugin_countryName
      } = res.data;
      const visitor = {
        ip: geoplugin_request,
        countrycode: geoplugin_countryCode,
        city: geoplugin_city,
        state: geoplugin_region,
        country: geoplugin_countryName
      } 

      socket.emit("new_visitor", visitor);

      socket.on("visitors", visitors => {
        this.setState({
          visitors: visitors
        })          
      })
    });
  }

But now the io.sockets.clients is not working anymore and is not recognized as a function.Every API provided seem t return only the Id. For anyone who knows a workaround on this please let us know. Thanks a lot.

Answer

Problem : How to hold custom data for each socket (serverside)

For each socket that connects to your socket-io server you want to be able to store some custom data in reference to said socket, so at a later point, other sockets can retrieve this information.

Solution : Add a simple in-memory-store (serverside)

I strongly advise to not add anything or mutating the socket object. Instead use the socket id to maintain a simple in-memory store for all connected sockets.

🚧 Please note: the following snippets are just pointers and are not meant to just be copy pasted. Instead, try to use them to understand your problem and adjust them to your needs.

Server Side

const store = {};

io.on('connection', function (socket) {

  // add socket to store, like this
  // note 'data' is null at this point, yet needs to be set
  store[socket.id] = {
    socket : socket, 
    data   : null
  }

  socket.on('SET_CLIENT_DATA', function (clientdata) {
    // here we receive data from frontend, and add it to the serverside reference
    store[socket.id].data = clientdata;
    
    // once a socket updates his custom client data
    // emit all custom data to all clients
    io.emit('ALL_CONNECTED_CLIENTS', Object.values(store).map(e => e.data));
  });

  socket.on('disconnect', function () {
    // if socket disconnects, make sure to remove the reference in your store
    delete store[socket.id];
  });

});

Client Side

socket.emit("SET_CLIENT_DATA", clientdata);

socket.on("ALL_CONNECTED_CLIENTS", (allclients) => {
  
/* here the client receives all custom client data that we kept serverside for each connected client */ 
/* do some more code here */

});


Source: stackoverflow