本文介绍了如何在单独的文件 Express.js 应用程序中定义 app.js 之外的所有 socket.io 逻辑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

期望的行为

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 以便:

  1. io.on('connection') 功能块中的所有逻辑都在 app.js
  2. 之外
  3. 可以在中间件文件中访问全局对象(logged_in_users 等)
  1. All logic in the io.on('connection') function block is outside of app.js
  2. 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 文件中

Node.js如何使用socket.io在快速路线

使用 socket.io 和 express 4 生成器

路由器页面中的NodeJS socket.io

在feathersjs中将socket.io逻辑与app.js分离

如何移动Socket.io io.on('connection') 编写另一个 js 文件?

将 Socket.io 分离成 app.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 逻辑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-26 04:28