Desired Behaviour
The socket.io initialisation docs provides this example, which I currently use in app.js
:
import { createServer } from "http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
I also have three objects before the io
block that need to be referenced from within the block:
var logged_in_users = {};
var users_in_rooms = {};
var live_edits_occurring = {};
As you can see, everything happens in app.js
.
I want to refactor app.js
so that:
- All logic in the
io.on('connection')
function block is outside ofapp.js
- The global objects (
logged_in_users
etc) are accessible in middleware files
Actual Behaviour
I am getting this error:
ReferenceError: logged_in_users is not defined
which means I cannot access logged_in_users
from a middleware file.
Question
How can I get the objects like logged_in_users
to be globally accessible?
So that they can be referenced and updated by all the middleware files?
Would app.locals be a good approach?
// app.js
app.locals.logged_in_users = {};
app.locals.users_in_rooms = {};
app.locals.live_edits_occurring = {};
I haven't used app.locals
before and I wouldn't know how to access app
within the middleware.
I also don't know if you can update app.locals
from middleware, which I would need to do.
What I've Tried
Following the docs on application structure, I have:
app.js
const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer);
const all_socketio_logic = require('./middleware/socketio/all_socketio_logic').all_socketio_logic;
const on_connection = async (socket) => {
all_socketio_logic(io, socket);
};
io.on('connection', on_connection);
/middleware/socketio/all_socketio_logic.js
import { heres_my_details } from './event_handler_heres_my_details';
const all_socketio_logic = (io, socket) => {
// i want these available in the middleware defined below
var logged_in_users = {};
var users_in_rooms = {};
var live_edits_occurring = {};
// sanity checks - all returning values - GOOD
console.log('socket.id is: ' + socket.id);
console.log('logged_in_users is: ');
console.log(logged_in_users);
console.log('users_in_rooms is: ');
console.log(users_in_rooms);
console.log('live_edits_occurring is: ');
console.log(live_edits_occurring);
// this is being returned to browser - GOOD
socket.emit('heres_your_socket_id', socket.id);
// this middleware is running - GOOD
socket.on('heres_my_details', heres_my_details);
/*
i will add other event handlers here:
socket.on('another_event_01', another_event_01);
socket.on('another_event_02', another_event_02);
etc
*/
};
export { all_socketio_logic };
/middleware/socketio/event_handler_heres_my_details.js
const heres_my_details = (data) => {
console.log('heres_my_details:');
console.log(data);
var username = data.username;
// if client is logged in
if (username !== null) {
var user_email = data.user_email;
/*
if the logged_in_users object doesn't already contain
the clients socket id (as a property), add the socket
id property and define object username and user_email
*/
if (!logged_in_users.hasOwnProperty(socket.id)) {
// the error is here - cannot access logged_in_users
logged_in_users[socket.id] = {};
logged_in_users[socket.id].username = username;
logged_in_users[socket.id].user_email = user_email;
console.log('logged_in_users AFTER ADDING new object:');
console.log(logged_in_users);
}
}
};
export { heres_my_details };
I get the following logged - GOOD:
socket.id is: zhWMY0EpkNAWURN3AAAB
logged_in_users is:
{}
users_in_rooms is:
{}
live_edits_occurring is:
{}
heres_my_details:
{
username: 'my username',
user_email: 'my@email_address.com',
logged_in: true
}
Error from event_handler_heres_my_details.js
- BAD:
ReferenceError: logged_in_users is not defined
Similar questions (with outdated or incomplete answers)
Use socket.io in expressjs routes instead of in main server.js file
Node.js how to use socket.io in express route
Using socket.io with express 4 generator
NodeJS socket.io in a router page
Separating socket.io logic from app.js in feathersjs
How to move Socket.io io.on('connection') code another js file?
Separate Socket.io into app.js
Separating file server and socket.io logic in node.js
Environment
node v16.13.0
express: ^4.17.1
socket.io: ^4.3.2
socket.io-client: ^4.3.2