使用(socket.io + RedisStore)跨多个服务器进行通信

时间:2014-04-24 03:23:59

标签: node.js redis socket.io load-balancing aws-opsworks

我正在使用Node.js和Socket.io开发多人在线游戏。我希望很多玩家加入游戏,所以我在亚马逊Opworks上托管它。

问题是服务器无法向连接到其他服务器的客户端发送套接字事件。我正在使用RedisStore来管理socket.io会话。我相信RedisStore和socket.io以无缝方式处理这种服务器间的通信。以下是对另一个问题的引用:How does socket.io send messages across multiple servers?

但事实并非如此。如果消息位于不同的服务器上,则消息不会通过其他客户端;如果只有一台服务器,该应用程序可以工作,但如果我在Opsworks上使用ELB使用多个服务器loadbalanced,则该应用程序会失败。

这只是整个代码的摘录。如果有的话,请忽略语法错误等。

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.

        }
      })

  })

});

1 个答案:

答案 0 :(得分:1)

您无法直接向其他服务器上的套接字对象广播。 Redis的功能是允许您向“房间”广播。在其他服务器上。值得庆幸的是,对于socket.io 1.x,新连接会自动加入一个房间,其名称为套接字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.

    } 

发送到房间而不是在套接字对象上调用emit:

   if(socket_id){

        io.to(socket_id).emit("message", {sender : sender}); // This fails. Messages to others servers dont go through.

    }

你可能会有更多的运气。