我遇到了一个奇怪的问题 - 在我的生产环境中(一切都在本地测试中运行正常) - socket.emit()工作正常,但io.emit()没有。换句话说,每个单独的套接字客户端连接可以向服务器发送和接收消息,但是当服务器发送到所有客户端时,它们都不会收到消息。这很奇怪,因为它可以看到所有客户端 - 如果我检查Object.keys(io.engine.clients)
我看到所有连接客户端的ID。但是io.emit()并没有向他们中的任何人广播。
我使用的是最新版本的节点(7.7.4和socket.io(1.7.3)。我在Heroku上托管,并启用了粘性会话。我使用群集以便所有CPU利用了,我设置了一个redis服务来同步所有工作人员。所有这些基础设施似乎都运行正常。
为什么socket.emit()适用于任何给定的套接字,但没有其他方法?
socket.on('sendChat', function(messageBundle) {
console.log('sockets: ' + Object.keys(io.engine.clients)) //shows clients
io.sockets.emit('incomingChat', messageBundle); //nothing
io.emit('incomingChat', messageBundle); //also nothing
var clients = Object.keys(io.engine.clients);
for (var i = 0; i < clients.length; i++) {
console.log('broadcasting to: ' + clients[i]);
socket.broadcast.to(clients[i]).emit('incomingChat', messageBundle); //still nothing
}
socket.emit('incomingChat', messageBundle); //this works though
});
更新:
这是我之前定义套接字的地方。
var redis = require('redis');
var pub = redis.createClient(redisPort, redisHost, {
auth_pass: redisPwd
});
var sub = redis.createClient(redisPort, redisHost, {
detect_buffers: true,
auth_pass: redisPwd
});
var adapter = require('socket.io-redis');
io.adapter(adapter({
pubClient: pub,
subClient: sub
}));
var cluster = require('cluster');
var WORKERS = process.env.WEB_CONCURRENCY || 3;
if (cluster.isMaster) {
for (var i = 0; i < WORKERS; ++i)
console.log('forking process ' + i);
cluster.fork();
} else {
var express = require('express');
var session = require('express-session');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var port = process.env.PORT || 5000;
server.listen(port, function() {
console.log("Listening on " + port);
console.log("testing");
});
var mySession = session({...}) //this enables me to authenticate the socket using the same session middleware as the express routes
io.use(function(socket, next) {
mySession(socket.handshake, {}, next);
});
io.on('connection', function(socket) {
socket.emit('welcome');
console.log('socket connection');
socket.on(... etc.)
...})
...})
在客户端,使用简单的配置启动套接字连接:
var socket = io({
reconnection: true,
reconnectionDelay: 100,
});
答案 0 :(得分:0)
io
一开始是未声明的,然后您尝试在else
语句中重新声明它。
答案 1 :(得分:-1)
对我来说,问题是 socket.io 和 reddis-adapter 的版本不匹配(将 socket io 升级到 3.0.1,redis 适配器保持在 5.x.x) 升级到6.0.1解决了