问题描述
期望的行为
socket.io 初始化文档 提供了这个示例,我目前在 app.js
中使用的:
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);
我在 io
块之前还有三个需要从块内引用的对象:
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 = {};
如您所见,一切都发生在 app.js
中.
As you can see, everything happens in app.js
.
我想重构 app.js
以便:
io.on('connection')
功能块中的所有逻辑都在app.js
之外- 可以在中间件文件中访问全局对象(
logged_in_users
等)
- 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
实际行为
我收到此错误:
ReferenceError:logged_in_users 未定义
这意味着我无法从中间件文件访问 logged_in_users
.
which means I cannot access logged_in_users
from a middleware file.
问题
如何让 logged_in_users
之类的对象可以全局访问?
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?
app.locals 会是一个好方法吗?>
Would app.locals be a good approach?
// app.js
app.locals.logged_in_users = {};
app.locals.users_in_rooms = {};
app.locals.live_edits_occurring = {};
我之前没有使用过 app.locals
,我不知道如何在中间件中访问 app
.
I haven't used app.locals
before and I wouldn't know how to access app
within the middleware.
我也不知道你是否可以从中间件更新 app.locals
,我需要这样做.
I also don't know if you can update app.locals
from middleware, which I would need to do.
我的尝试
遵循有关应用程序结构的文档,我有:
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
}
来自 event_handler_heres_my_details.js
的错误 - 错误:
Error from event_handler_heres_my_details.js
- BAD:
ReferenceError:logged_in_users 未定义
类似问题 (答案过时或不完整)
使用套接字.io 在 expressjs 路由中而不是在主 server.js 文件中
在feathersjs中将socket.io逻辑与app.js分离
如何移动Socket.io io.on('connection') 编写另一个 js 文件?
分离文件服务器和 socket.io 中的逻辑node.js
环境
节点 v16.13.0
快递:^4.17.1
socket.io:^4.3.2
socket.io-客户端:^4.3.2
node v16.13.0
express: ^4.17.1
socket.io: ^4.3.2
socket.io-client: ^4.3.2
推荐答案
一种方法:
app.js
const express = require('express');
const { createServer } = require('http');
const app = express();
const httpServer = createServer(app);
const io = require('./ws.js')(httpServer);
ws.js
module.exports = function ws(httpServer) {
var logged_in_users = {};
var users_in_rooms = {};
var live_edits_occurring = {};
const { Server } = require('socket.io');
const io = new Server(httpServer);
httpServer.use(function(req, res, next){
// attach io, etc. to every req object
req.ws = {
io,
logged_in_users,
users_in_rooms,
live_edits_occurring
};
// call next to pass req to handler
next();
});
io.on('connection', on_connection);
};
这篇关于如何在单独的文件 Express.js 应用程序中定义 app.js 之外的所有 socket.io 逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!