【问题标题】:NodeJS + Socket.IO : Problem accessing room variablesNodeJS + Socket.IO:访问房间变量的问题
【发布时间】:2021-03-02 16:46:12
【问题描述】:

我是 NodeJS 和 Socket.io 技术的新手,我遇到了存储在 io.sockets.adapter.rooms 中的变量的问题。

我有我的 app.js:

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('message', function (room) {
      socket.join(room);
      console.log(io.sockets.adapter.rooms);
      io.sockets.adapter.rooms[room].variable = "This is a test";
  })
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

index.html :

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
    <input type="button" value="Press me" id="test">
<body>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();
        document.getElementById('test').addEventListener('click', function () {
            socket.emit('message', 'room1');
        })
    </script>
</body>

</html>

服务器返回此错误:

TypeError: Cannot set property 'variable' of undefined

这意味着“io.sockets.adapter.rooms[room].variable”未定义,但我不明白如何定义它。

顺便说一句,我使用的是 NodeJS 12.8.3 和 express 4.17.1

也许我需要一个特定的模块?

非常感谢所有愿意花时间回答这个问题的人

【问题讨论】:

  • 在 socket.io 的某些版本(2.x 和更早版本)和某些配置中,socket.join() 是异步的,直到稍后您可以传递的可选回调为叫。因此,您可能正在尝试在房间创建之前访问它。我认为 socket.io 的绝对最新版本(版本 3.x)实际上已经使 socket.join() 同步,因此它会立即完成并且您的代码可以工作。
  • 我有socket.io 3.0.3 版本,但是不工作,可能需要另一个模块?

标签: javascript node.js express sockets socket.io


【解决方案1】:

v3.0.0 的更改日志中,他们提到了以下内容
Socket#rooms 现在是一个 Set 而不是一个对象

这意味着它现在是 Map object 而不是 normal js object

因此,使用 v3.0.3 时,您在记录房间时会得到以下输出,您无法像普通 js 对象那样通过键访问,而必须使用 .set() 代替。

Map(2) {
  'II-OqYrpZYtv2bKrAAAD' => Set(1) { 'II-OqYrpZYtv2bKrAAAD' },
  'room1' => Set(1) { 'II-OqYrpZYtv2bKrAAAD' }
}

虽然我不知道如何为房间添加一个额外的变量。因为如果你运行以下代码:

io.sockets.adapter.rooms.set(room, {
  variable: "Test variable"
})

它将套接字 id 替换为新变量。我找不到任何关于他们希望我们如何使用这种新结构来存储变量的信息。

Map(2) {
  'Xv6vbxuOgDuqp6dmAAAB' => Set(1) { 'Xv6vbxuOgDuqp6dmAAAB' },
  'room1' => { variable: 'Test variable' }
}

使用 v2.0.3 记录房间时,您会得到一个正常的对象输出,您可以使用 [key] 访问它。

{
  'tVnQpZyKDglSf4J-AAAA': Room { sockets: { 'tVnQpZyKDglSf4J-AAAA': true }, length: 1 },
  room1: Room { sockets: { 'tVnQpZyKDglSf4J-AAAA': true }, length: 1 }
}

因此,如果您将 socket.io 恢复到 v2.0.3(最新的 2.x.x 版本),您的代码就可以正常工作。

您可以通过运行以下命令来恢复 socket.io

npm i socket.io@2.0.3

或者通过更改package.json中的版本号然后运行

npm install

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 2019-05-13
    • 2015-03-24
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 2021-05-09
    相关资源
    最近更新 更多