You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用socket.io-redis时调用provider_join方法出现TypeError: io.of(...).sockets.get is not a function错误求助

解决 TypeError: io.of(...).sockets.get is not a function 问题

这个错误的核心原因是你误解了 io.of("/").sockets 的作用和结构,再加上使用Redis适配器时的特殊情况,导致调用了不存在的方法。让我一步步帮你解决:

为什么会报错?

  • io.of("/").sockets 是当前服务器节点上所有Socket连接实例的集合,但它不是ES6 Map类型,所以并没有 get() 方法。
  • 更关键的是:你想要判断的是「房间是否存在」,而 sockets 存储的是连接实例,不是房间信息。当使用Redis适配器时,房间信息是跨节点同步的,存储在 io.of("/").adapter.rooms 中。

修复后的代码

我帮你调整了逻辑,移除了容易引发并发问题的全局变量,改用正确的方式判断房间:

const express = require('express')
const app = express()
const server = require('http').createServer(app)
const io = require('socket.io')(server)
const redisAdapter = require('socket.io-redis');

// 注意:默认Redis端口是6379,如果你确实用8000可以保留,否则建议改成6379
io.adapter(redisAdapter({ host: 'localhost', port: 8000 }));
io.of('/').adapter.on('error', function(err){
  console.error('Redis适配器错误:', err); // 建议加上错误日志,方便排查
});

io.on('connection', (socket) => {
  socket.on('provider_join' , (providername) => {
    // 通过Redis适配器的rooms Map判断房间是否存在
    const roomExists = io.of("/").adapter.rooms.has(providername);
    
    if(!roomExists){
      socket.join(providername);
      socket.emit('room_created', providername);
    } else {
      socket.emit('room_already_created', providername);
    }
  })
})

关键说明

  1. 用 adapter.rooms 判断房间:Redis适配器会自动同步所有集群节点的房间信息,io.of("/").adapter.rooms 是一个标准的ES6 Map,你可以用 has() 方法检查房间是否存在,用 get() 获取房间内的Socket ID集合。
  2. 移除全局变量 room:原来的全局变量会导致多个用户请求互相干扰,因为所有连接共享同一个全局变量,这是典型的并发问题。
  3. 错误日志建议:给Redis适配器的error事件加上日志,方便后续排查Redis连接或同步问题。

内容的提问来源于stack exchange,提问作者Mohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 05:12:37