0

I am quite new to node.js and don't understand how to solve the following:

I have an express app and want to use socket.io in a sub file to get smaller code blocks - I want to excclude the socket.io part to a file called data.js - from what I have read here this is a proper way to use io on sub-files:

const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const io = require('socket.io')(server); require('.data')(io); // .... start server etc. below. 

in the data.js file i have:

const consola = require('consola'); module.exports = function (io) { io.on('connection', (socket) => { consola.success(`User connected - ${io.engine.clientsCount} online`); socket.on('disconnect', (socket) => { consola.success(`user disconnected :(`); }); }); }; 

so far that works. I have acces to io in the data.js. Now I want to emit a message outside the function(io). Reason is that I have an interval in the data.js that checks for new data. When it detects new data, the data should be forwarded via socket.io to the connected clients. But I don't want to put the interval inside the 'connection' as this would trigger a new interval evertime a user joins. So I want to emit from another function inside data.js...

can someone please point me to the right direction please. I already found some solutions here, but it seems they all only work if you have the sockets logic in the file with the express logic.

Many thanks in advance.

1 Answer 1

2

Perhaps something like below would solve your problem? Basically you emit to all of the sockets every N milliseconds.

const consola = require('consola'); module.exports = function (io) { io.on('connection', (socket) => { consola.success(`User connected - ${io.engine.clientsCount} online`); socket.on('disconnect', (socket) => { consola.success(`user disconnected :(`); }); }); setInterval(() => { io.sockets.emit('hi', 'everyone'); }, 5000 /* Your configurable time */); }; 

We can make it a bit more configurable passing the refresh rate to the module function.

const consola = require('consola'); module.exports = function (io, timeout) { io.on('connection', (socket) => { consola.success(`User connected - ${io.engine.clientsCount} online`); socket.on('disconnect', (socket) => { consola.success(`user disconnected :(`); }); }); if (timeout && timeout > 500) { /* Ensuring we don't update more frequently than half a second */ setInterval(() => { io.sockets.emit('hi', 'everyone'); }, timeout/* Your configurable time */); } }; 

If for some reason you absolutely need to move the io outside of the function scope - you can do it like:

const consola = require('consola'); var socketIO; module.exports = function (io, timeout) { socketIO = io; configureTimeout(timeout); socketIO.on('connection', (socket) => { consola.success(`User connected - ${io.engine.clientsCount} online`); socket.on('disconnect', (socket) => { consola.success(`user disconnected :(`); }); }); }; configureTimeout(timeout) { if (timeout && timeout > 500) { /* Ensuring we don't update more frequently than half a second */ setInterval(() => { socketIO.sockets.emit('hi', 'everyone'); }, timeout/* Your configurable time */); } } 
Sign up to request clarification or add additional context in comments.

4 Comments

Hi Mavi, many thanks for your reply. Maybe i was not clear enough in my question, sorry. My problem is that I cant access io outside the module.exports = function (io) {} ... so your solution does also not work for me. I don't understand how to access io outside the function (io) {}
Edited my answer - can you please clarify why do you want to move this functionality outside of the function(io) ? These work with callbacks, which means you are in a different function when you are executing (socket) = >{ some operations }
Thanks for your edit. That worked as expeced. I tried this before posting here and it didn't. No idea why it now does.... maybe i should take a break ;) EDIT: I need this because I have an interval in this file which polls a data source once a second. The result of zhis poll is checked by my code and I want only to fire an emit if the result from the interval has new data (which depends on the result of other code).
Depending on where you write the socketIO.sockets.emit, it might not have worked. My guess is you tried to access the socket rather than the io but who knows :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.