Node.js get same instance of module accross different classes - node.js

I've a main class (app.js) where I declared an instance of socket-io and I would like to know how is possible to get same instance of socket-io inside another classes.
app.js
var io = require('socket.io')();
//initialize socket and more related do web socket
routes.js
var io = ?? //How get same var io from app.js?
On Node.js, is possible to do that? I need to manipulate some informations from socket-io but I would like to avoid write a single file with all logic inside.

Let's say you have a file routes.js and this is a file inside which you want to access the instance of socket-io which you have created on app.js. Then you can pass this var io inside the routes.js file that will pass the same instance of socket-io like this,
Inside app.js
var io = require('socket.io')();
//pass the `io` inside the route file
require('routes')(io);
Inside routes.js
module.exports = function(io) {
//your route codes here that can access `io`
};

Related

I'm trying to access socket.io in an express-generator app, but getting a null object

I've built a web app with express generator. I'd like to be able to send updates to the browser from a number of different modules.
However, I'm not quite sure why the solution I've put together, below, doesn't work.
I know that the exports.initialize() function is being called, through logging to the console, but the error I'm getting, cannot read property 'emit' of null suggests that socket.io is not being initialized, because it's returning a null object.
I've created a module containing the below wrapper:
const sio = require('socket.io')
let io = null
exports.io = function () {
return io
}
exports.initialize = function(server) {
console.log("init")
return io = sio(server)
}
I've initialised the module in my app.js file, like so:
// Create the http server
const server = require('http').createServer(app);
// Create the Socket IO server on
// the top of http server
const io = require('./app_modules/sockets').initialize(server)
and then, in modules where I need to send information to the browser, I'm calling the sockets module like this:
const io = require('./sockets').io()
Can anyone help me understand why this isn't working, and what I can do to fix it?
In order to start a Socket.IO server, you need to invoke the Server constructor. The io constructor is only for the client side.
Your sockets module should look like this:
const sio = require('socket.io')
let io = null
exports.io = io
exports.initialize = function(server) {
io = new sio.Server(server);
return io
}
And in modules where you need to send information to the clients, you should use something like this:
const io = require('./sockets').io

How to use static variable in node js?

I am try to load country names and want to save them in static variable. So that I do not hit in my database again and again.
I am using express Js.
Please suggest me How can i load country name in optimize ways
In node.js, modules are cached after the first time they are loaded. Every call to import/require will retrieve exactly the same object.
A good way to achieve this is:
app.js
var app = require('express')(),
server = require('http').createServer(app);
var lookup=require('./lookup.js');
server.listen(80, function() {
//Just one init call
lookup.callToDb(function(){
console.log('ready to go!');
});
});
lookup.js
callToDb(function (country){
module.exports=country;
});
and wherever you require:
model.js
var countryLookup= require('./lookup.js');

Two way communication between routers within express app

I have an express app that has a router for different sections of my application, each contained within individual files. At the end of each file I export the router object like so.
var express = require("express");
var router = express.Router();
//routing handlers
module.exports = router;
However my problem is that I am trying to implement a feature were a user is allowed to edit a post that could be displayed on the front page, therefore in order to have the most current version of the user's post I need to be able to know when the user edits the post to make the necessary changes.
I have two modules one that handles dispatching the user's posts call this module B and another that handles editing call this module A. I need to be able to have module A include handler function and an array from module B, but I also need module B to be able to be notified when to make changes to the its array that module A requires.
I have tried
module A
var express = require('express');
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
var router = express.Router();
var modB = require('moduleB');
router.evt = evt;
module.exports = router;
Module B
var express = require('express');
var router = express.Router();
var modA = require('moduleA').evt;
modA.on('myEvent',handler);
var myArray = [....];
router.myArray = myArray;
module.exports = router;
This gives me an undefined for modA and throws an error. I suspect it might be the order the modules are included but anyhow I would like to obtain some feedback since I sense that this might not even be good practice.
I think you are running into a common scenario for someone just starting out with express. A lot of people stick everything into routes/controllers when really the route should be very simple and just extract the data needed to figure out what the request is doing and then pass it to a service for most of the processing.
The solution is to create a Service and put the bulk of your logic and common code there, then you can wire up ModA and ModB to use the Service as needed.
EDIT with an example(not working but should give you a good starting point):
Shared Service
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
module.exports = {
saveData: function(data) {
// do some saving stuff then trigger the event
evt.emit('myEvent', data);
},
onDataChange: function(handler) {
evt.on('myEvent', handler);
}
};
Module A
var service = require('SharedService.js');
// listen for events
service.onDataChange(function(e, data) {
// do something with the data
});
Module B
var service = require('SharedService.js');
// save some data which will cause Module A's listener to fire
service.saveData(data);
This example above hides the implementation of EventEmitter which may or may not be desirable. Another way you could do it would be to have SharedService extend EventEmitter, then your Modules could listen/emit directly on the service.

Cannot access io object in session.socket.io

I am using session.socket.io for my app
o = require('socket.io').listen(tmpServer),
appCookieParser = express.cookieParser(settings.cookie.secret),
appRedisStore = new RedisStore(),
sessionIO = new SessionSockets(io, appRedisStore, appCookieParser
App.app.use(appCookieParser)
App.app.use(express.session({
store: appRedisStore
}))
Note that App is a global variable which holds some of my app data and some helper functions, as I followed the LearnAllTheNodes application structure.
Then I define the callback on connection
sessionIO.on('connection', socketHandler)
where socketHandler is a function returned by a require call.
module.exports = function(err, socket, session) {
console.log(io.sockets.clients('a'))
socket.join('a')
console.log(io.sockets.clients('a'))
}
According to the documentation I should have access to my io object, but I am always getting the error that io is not defined.
Note that if I am emitting some events or listening for some events in the sockatHandler I am getting/sending them properly. Just I have no access to io.
UPDATE
It turns out it works perfectly if I am implementing the callback function as an anonymous function. The documentation is confusing, it should be: you can use io if you have a reference to it.
You seem to have forgotten to define io which here should be the listener.
According to the code you display, you should probably have something like
var app = express();
var server = http.createServer(app);
var io = socketio.listen(server);
Here's an example of a complete application using express, socket.io and session.socket.io.
To make my app less crowded I've updated the socketHandler so it takes all my socket related objects
socketHandler(sessionIO, io)
and I am handling the socket operations in another module via these objects.

Node.js - sharing sockets among modules with require

I'm using socket.io. In app.js I set up it and whenever a connection is established, I add the new socket to sockets array. I want to share sockets among modules such as routes by require(). However, app.js also requires the routes, so it forms a require loop. Here's the code.
// app.js
var route = require('routes/route')
, sockets = [];
exports.sockets = sockets;
// route.js
var sockets = require('../app').sockets; // undefined
How can I resolve the loop? Or are there other approaches?
You could do all your socket.IO work inside the route file
var route = require('routes/route').init(io)
with in routes.js
var io;
exports.init = function(io) {
io = io
}

Resources