Я работаю над многопользовательской онлайн-игрой, используя Node.js и Socket.io. Я ожидаю, что к игре присоединится много игроков, поэтому я размещаю ее на Amazon Opworks.
Проблема в том, что серверы не могут отправлять события сокетов клиентам, подключенным к другому серверу. Я использую RedisStore для управления сеансами socket.io. Я полагал, что RedisStore и socket.io позаботились об этом межсерверном взаимодействии под капотом без проблем. Вот ссылка на другой вопрос: Как работает socket. io отправлять сообщения на несколько серверов?
Но это не тот случай, кажется. Сообщения не доходят до других клиентов, если они находятся на разных серверах; приложение работает, если есть только один сервер, но не работает, если я использую несколько серверов с балансировкой нагрузки с помощью ELB в Opsworks.
Это просто выдержка из всего кода. Пожалуйста, игнорируйте синтаксические ошибки и т. д., если они есть.
app.js
//Redis Client Initialization
var redis = require("redis");
redis_client = require('redis-url').connect('redis://xxxxx');
//setting RedisStore for socket.io
var RedisStore = require('socket.io/lib/stores/redis')
, redis = require('socket.io/node_modules/redis')
, pub = redis.createClient(11042,'-----')
, sub = redis.createClient(11042,'-----')
, client = redis.createClient(11042,'-----');
// using RedisStore in combo with Socket.io to allow communications across multiple servers
io.set('store', new RedisStore({
redis : redis,
redisPub : pub,
redisSub : sub,
redisClient : client
}));
//socket communication specific code
io.of('/game')
.on('connection', function (socket) {
socket.on('init' , function(data){
var user_id = data.user_id; // collecting user_id that was sent by the client
var socket_id = socket.id;
redis_client.set("user_socket:"+user_id, socket_id, function(err, reply){
//stored a referece to the socket id for that user in the redis database
});
});
socket.on('send_message', function(data){
var sender = data.sender_id;
var reciepient = data.reciepient_id ; // id of the user to whom message is to be sent to
redis_client.get("user_socket:"+reciepient, function(err,socket_id){
if(socket_id){
var socket = io.of('/game').sockets[socket_id];
socket.emit("message", {sender : sender}); // This fails. Messages to others servers dont go through.
}
})
})
});