简体   繁体   English

Socket.io并不总是在Node.js + Redis + Heroku(多个dynos)环境中收到

[英]Socket.io emits not always recieved on Node.js + Redis + Heroku (multiple dynos) environment

Environment Context 环境背景

We are running a Node.js v0.10.25 app with Socket.io v0.9.16 on Heroku. 我们在Heroku上运行了一个带有Socket.io v0.9.16Node.js v0.10.25应用程序。 We are using redis v2.6 , more specifically the Heroku add-on "redis to go", as the socket store. 我们使用redis v2.6 ,更具体地说是Heroku附加组件“redis to go”,作为套接字商店。 We currently have two dynos running. 我们目前有两个dynos在运行。

Problem 问题

The problem is that the socket connections via xhr-polling are sent to a socket but not always received on the same socket. 问题是通过xhr-polling的套接字连接被发送到套接字但不总是在同一套接字上接收。 An example: 一个例子:

  • We emit a heartbeat server side. 我们发出心跳服务器端。
  • We do not always receive a response client side. 我们并不总是收到响应客户端。

Server Side Code 服务器端代码

var app = require('express')()
      , server = require('http').createServer(app)
      , io = require('socket.io').listen(server);
    server.listen(3001);

    var RedisStore  = require('socket.io/lib/stores/redis')
    var redis       = require('redis')

    var rtg         = require("url").parse(FULL_REDIS_PATH);
    var hostname    = rtg.hostname;
    var database    = rtg.auth.split(":")[0];
    var portRedis   = rtg.port;
    var password    = rtg.auth.split(":")[1];

    var pub         = redis.createClient(portRedis, hostname)
    var sub         = redis.createClient(portRedis, hostname)
    var client      = redis.createClient(portRedis, hostname)

    pub.auth(password, function (err) { if (err) throw err; });
    sub.auth(password, function (err) { if (err) throw err; });
    client.auth(password, function (err) { if (err) throw err; });

    /** Initialize RedisStore for socket.io **/
    io.set('store', new RedisStore({
      redis    : redis
    , redisPub : pub
    , redisSub : sub
    , redisClient : client
    }));

    /** Configuration Settings for socket.io **/
    io.set('log level', 1);
    io.set('transports', ['flashsocket','xhr-polling']);
    io.set('polling duration', 10);

    io.sockets.on('connection', function (socket) {

        /** Associate Client ID to Socket ID **/
        client.set('client-'+client_id,socket.id, function(err){
                if (err) throw err;
                console.log("User " + client_id + " socket is now... " + socket.id);
                /**
                * Retrieve the Socket ID by the User's ID
                * Send a socket.emit message based on the Socket ID retrieved from Redis.
                **/
                client.get('client-'+client_id,function(err, response){
                    socketId = response;
                    io.sockets.socket(socketId).emit('response',{user_id: client_id});
                    console.log('Retrieving User ' + client_id + ' - socket is now... ' + socket.id);
            });
        });
    });

Client Side Code 客户端代码

<script src="http://localhost:3001/socket.io/socket.io.js"></script>
<script>
        var socket = io.connect('http://localhost:3001');

        socket.on('response', function (data) {
            console.log(data);
        });
</script>

Any help on this would be greatly appreciated, thanks in advance! 对此有任何帮助将非常感谢,提前感谢!

If by "We currently have two dynos running." 如果“我们目前有两个dynos在运行”。 you mean that you have two instances of your server, communicating via the redis pub/sub, then this should be what your ooking for: http://socket.io/docs/using-multiple-nodes/ 你的意思是你有两个你的服务器实例,通过redis pub / sub进行通信,那么这应该是你的ooking: http ://socket.io/docs/using-multiple-nodes/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM