【发布时间】:2022-01-08 02:21:19
【问题描述】:
期望的行为
socket.io initialisation docs 提供了这个示例,我目前在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);
io 块之前还有三个对象需要在块内引用:
var logged_in_users = {};
var users_in_rooms = {};
var live_edits_occurring = {};
如您所见,一切都发生在app.js。
我想重构 app.js 以便:
-
io.on('connection')功能块中的所有逻辑都在app.js之外 - 可以在中间件文件中访问全局对象(
logged_in_users等)
实际行为
我收到此错误:
ReferenceError:logged_in_users 未定义
这意味着我无法从中间件文件访问logged_in_users。
问题
我怎样才能让像logged_in_users 这样的对象可以全局访问?
以便它们可以被所有中间件文件引用和更新?
app.locals 会是一个好方法吗?
// app.js
app.locals.logged_in_users = {};
app.locals.users_in_rooms = {};
app.locals.live_edits_occurring = {};
我之前没有使用过app.locals,也不知道如何在中间件中访问app。
我也不知道你是否可以从中间件更新app.locals,我需要这样做。
我的尝试
关注the docs on application structure,我有:
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 };
我得到以下记录 - 好:
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
}
来自event_handler_heres_my_details.js 的错误 - 错误:
ReferenceError:logged_in_users 未定义
类似问题 (答案已过时或不完整)
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
环境
节点 v16.13.0
快递:^4.17.1
socket.io: ^4.3.2
socket.io-client: ^4.3.2
【问题讨论】: