I am working on a multiplayer online game, using Node.js and Socket.io. I expect a lot of players to join the game, so I am hosting it on Amazon Opworks.
The problem is that the servers aren't able to send socket events to clients connected to a different server. I am using RedisStore to manage socket.io sessions. I believed RedisStore and socket.io took care of this inter-server communication under the hood in a seamless manner. Here is a reference to another question: How does socket.io send messages across multiple servers?
But that's not the case it seems. Messages do not go through to other clients if they are on different servers; the app works if there is only one server, but fails if I use multiple servers loadbalanced using ELB on Opsworks.
This is just an extract from the whole code. Please ignore syntax errors etc if any.
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.
}
})
})
});