How can i export socket.io into other modules in nodejs?
Solution 1:
Since app.js is usually kind of the main initialization module in your app, it will typically both initialize the web server and socket.io and will load other things that are needed by the app.
As such a typical way to share io
with other modules is by passing them to the other modules in that module's constructor function. That would work like this:
var server = require('http').createServer(app);
var io = require('socket.io')(server);
// load consumer.js and pass it the socket.io object
require('./consumer.js')(io);
// other app.js code follows
Then, in consumer.js:
// define constructor function that gets `io` send to it
module.exports = function(io) {
io.on('connection', function(socket) {
socket.on('message', function(message) {
logger.log('info',message.value);
socket.emit('ditConsumer',message.value);
console.log('from console',message.value);
});
});
};
Or, if you want to use a .start()
method to initialize things, you can do the same thing with that (minor differences):
// app.js
var server = require('http').createServer(app);
var io = require('socket.io')(server);
// load consumer.js and pass it the socket.io object
var consumer = require('./consumer.js');
consumer.start(io);
// other app.js code follows
And the start method in consumer.js
// consumer.js
// define start method that gets `io` send to it
module.exports = {
start: function(io) {
io.on('connection', function(socket) {
socket.on('message', function(message) {
logger.log('info',message.value);
socket.emit('ditConsumer',message.value);
console.log('from console',message.value);
});
});
};
}
This is what is known as the "push" module of resource sharing. The module that is loading you pushes some shared info to you by passing it in the constructor.
There are also "pull" models where the module itself calls a method in some other module to retrieve the shared info (in this case the io
object).
Often, either model can be made to work, but usually one or the other will feel more natural given how modules are being loaded and who has the desired information and how you intend for modules to be reused in other circumstances.
Solution 2:
If you want to avoid the global scope, make your io
exist in a separate file like this:
var sio = require('socket.io');
var io = null;
exports.io = function () {
return io;
};
exports.initialize = function(server) {
return io = sio(server);
};
Then in app.js
:
var server = require('http').createServer(app);
var io = require('./io').initialize(server);
require('./app/consumers/ditconsumer'); // loading module will cause desired side-effect
server.listen(...);
and in consumer.js
:
require('../io').io().on('connection', function(socket) {
logger.log('info', message.value);
socket.on('message', function(message) {
socket.emit('ditConsumer',message.value);
console.log('from console',message.value);
});
});
Solution 3:
I found a simple solution. Use a global variable in app.js and access it from the other files.
global.io = require('socket.io').listen(server);
Solution 4:
You can make a singleton instance in just 4 lines.
In websocket.js write your server configuration code.
const socketIO = require('socket.io');
const server = require('http').createServer();
server.listen(8000);
module.exports = socketIO(server);
Then in your consumer.js just require the file
const socket = require('./websocket');
/* API logic here */
socket.emit('userRegistered', `${user.name} has registered.`);
Solution 5:
What worked best for me was to use a callback function which exports the socket.io instance. app.js:
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket) {
socket.on('message', function(message) {
logger.log('info',message.value);
socket.emit('ditConsumer',message.value);
console.log('from console',message.value);
});
});
function getSocketIo(){
return io;
}
module.exports.getSocketIo=getSocketIo
and in the consumer.js
const app=require('./app.js')
const io=app.getSocketIo()