0

Dear all,

Im working with JS for some weeks and now I need a bit of clarification. I have read a lot of sources and a lot of Q&A also in here and this is what I learned so far.

Everything below is in connection with Node.js and Socket.io

  • Use of globals in Node.js "can" be done, but is not best practice, terms: DONT DO IT!
  • With Sockets, everything is treated per socket call, meaning there is hardly a memory of previous call. Call gets in, and gets served, so no "kept" variables.

Ok I build up some chat example, multiple users - all get served with broadcast but no private messages for example.

Fairly simple and fairly ok. But now I am stuck in my mind and cant wrap my head around.

Lets say:

  • I need to act on the request
  • Like a request: "To all users whose name is BRIAN"

In my head I imagined:

1. Custom object USER - defined globally on Node.js

function User(socket) {
this.Name;
this.socket = socket; }

2. Than hold an ARRAY of these globally

users = [];

and on newConnection, create a new User, pass on its socket and store in the array for further action with

users.push(new User(socket));

3. And on a Socket.io request that wants to contact all BRIANs do something like

for (var i = 0; i < users.length; i++) {
if(user[i].Name == "BRIAN") {
    // Emit to user[i].socket
}}

But after trying and erroring, debugging, googling and reading apparently this is NOT how something like this should be done and somehow I cant find the right way to do it, or at least see / understand it. can you please help me, point me into a good direction or propose a best practice here? That would be awesome :-)

Note: I dont want to store the data in a DB (that is next step) I want to work on the fly.

Thank you very much for your inputs

Oliver

1 Answer 1

1

first of all, please don't put users in a global variable, better put it in a module and require it elsewhere whenever needed. you can do it like this:

users.js

var users = {
    _list : {}
};

users.create = function(data){
  this._list[data.id] = data;
}

users.get = function(user_id){
    return this._list[user_id];
};

users.getAll = function(){
    return this._list;
};
    
module.exports = users;

and somewhere where in your implementation

var users = require('users');

For your problem where you want to send to all users with name "BRIAN", i can see that you can do this good in 2 ways.

First. When user is connected to socketio server, let the user join a socketio room using his/her name. so it will look like this:

var custom_namespace = io.of('/custom_namespace');
custom_namespace.on('connection', function(client_socket){
    //assuming here is where you send data from frontend to server
    client_socket.on('user_data', function(data){
        //assuming you have sent a valid object with a parameter "name", let the client socket join the room 
        if(data != undefined){
            client_socket.join(data.name); //here is the trick
        }
    });
});

now, if you want to send to all people with name "BRIAN", you can achieve it by doing this

io.of('/custom_namespace').broadcast.to('BRIAN').emit('some_event',some_data);

Second. By saving the data on the module users and filter it using lodash library

sample code

var _lodash = require('lodash');
var Users = require('users');
var all_users = Users.getAll();
var socket_ids = [];
var users_with_name_brian = _lodash.filter(all_users, { name : "BRIAN" });

users_with_name_brian.forEach(function(user){
   socket_ids.push(user.name);
});

now instead of emitting it one by one per iteration, you can do it like this in socketio

io.of('/custom_namespace').broadcast.to(socket_ids).emit('some_event',some_data);

Here is the link for lodash documentation

I hope this helps.

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

2 Comments

Wow Theo! Thank you very very much. Good! This makes, sense and definitely helps me to go further. Okay :) thank you, Ill continue my jurney :-)
Happy to help mate

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.