1

In my chat application using nodejs and socket.io, I need to share variable across different modules such that the value modified on one file should be accessed from other file. A workflow of my app is as follows.

In main app.js I have included a controller file for authenticating "users.js" In which I use a variable say for example var onlineusers ={}; On each login, the value is inserted into this variable. For handling socket chat, I used another controller file named chat.js where I need to use the same variable onlineusers.

Now Consider 3 files app.js,user.js,chat.js

In app.js
var users = require('./users.js');
var chat = require('./chat.js');
users.set(app);
chat.set(app,io);


In user.js

module.exports.set = function(app) {
// var onlineusers  modified in some function
}

In chat.js

module.exports.set = function(app,io) {
// var onlineusers  modified in some function
}

What i need is sharing the variable var onlineusers value across different modules(user.js and chat.js)

3
  • Store the variable in one module and export a method that retrieves the value. You can then get the value of the same variable from either module. Commented Jan 9, 2017 at 7:01
  • One more query, Does it affect the performance if the number of online users increases. Also I need to use variables for rooms as well Commented Jan 9, 2017 at 8:19
  • No, this doesn't affect the performance as online users increase in any way. There's one module instance loaded in your server period. You're just creating an accessor function to get at some data stored in the module. That's a common and good way to share data that has no scalability downsides. Commented Jan 9, 2017 at 8:25

1 Answer 1

2

What I would do is change chat.js and user.js .set functions to accept another paramter called onlineUsers. Then from app.js you can pass an onlineUsers value to each modifying .set functions.

// In app.js
var users = require('./users.js');
var chat = require('./chat.js');
var onlineUsers = new require('./onlineUsers')();
users.set(app, onlineUsers);
chat.set(app,io, onlineUsers);

// In user.js
module.exports.set = function(app, onlineUsers) {
  // onlineusers modified in some function
};

// In chat.js
module.exports.set = function(app, io, onlineUsers) {
  // onlineusers modified in some function
};

// In onlineUsers.js
module.exports = function(params) {
  // constructor for onlineUsers data model
};

This works because JavaScript passes by value.

'use strict';
let obj = {};
(function firstModifier(obj) { 
  obj.first = true;
})(obj);
console.log(obj);

This will only work to an extent. I would strongly consider using a database for this type of work. For managing online users with node & socket.io, I've found mongodb and redis to both be really good choices. The worthwhile benefit of this is your onlineUsers collection is databased instead of using an onlineUsers variable in application memory. Then your application can just access the db instead of "sharing" a variable.

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

7 Comments

Thanks for your answer. One question what you think about using global variable in seperate file "onlineUsers.js" like you mentioned above instead of database. If we use database, it can cause some delay on execution at different updation and fetching also concurrency issues?. So I am planing to use variable, but I am anxious about why you said that "Variable will work to an extend"
It will work to an extent in that you are limited to application memory. This could very well be more than fine for your use. If you have a lot of online users and are storing sizable amounts of data on each of those users (i.e. an array of big objects), then one instance of a node process might not do the job. See stackoverflow.com/questions/7193959/…. I think using onlineUsers.js as above or using @jfriend00's approach is perfectly fine if you don't expect to manage that many users.
I will add that by having online users data stored in a variable inside of one node process you'll lose all that data when that process dies. So if this is for a learning experience or small project its tots cool - but you couldn't do something like this with a user base and expect good results.
@Ajith in addition to what Yod says, overhead for something like Redis can be as little as few milliseconds, if your Redis node is close. E.g. on AWS, latency from Node apps to Redis is 1-2ms. Add some management overhead and it's still probably under 5ms. So you shouldn't be afraid of that.
Another point is that if you're afraid that your load will hit concurrency and delays, you're probably even more likely your in-memory will get stuck.
|

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.