使用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); } }) })
关键说明
- 用
adapter.rooms判断房间:Redis适配器会自动同步所有集群节点的房间信息,io.of("/").adapter.rooms是一个标准的ES6 Map,你可以用has()方法检查房间是否存在,用get()获取房间内的Socket ID集合。 - 移除全局变量
room:原来的全局变量会导致多个用户请求互相干扰,因为所有连接共享同一个全局变量,这是典型的并发问题。 - 错误日志建议:给Redis适配器的error事件加上日志,方便后续排查Redis连接或同步问题。
内容的提问来源于stack exchange,提问作者Mohan
相关产品推荐
相关产品推荐

