복붙노트

[REDIS] 내 클러스터 Node.js를 / socket.io / 레디 스 펍 / 하위 응용 프로그램에서 중복 메시지를 수신하고 있습니다

REDIS

내 클러스터 Node.js를 / socket.io / 레디 스 펍 / 하위 응용 프로그램에서 중복 메시지를 수신하고 있습니다

나는 Redisstore의 Socket.io들에서 클러스터와 레디 스와 Node.js를, Socket.io를 사용하고 있습니다.

나는 한 Node.js를 노드에서 잘 작동 술집 / 하위 응용 프로그램을했습니다. 이 부하 때 Node.js를이 멀티 코어 시스템 용으로 작성되지 않기 때문에 그러나, 서버의 한 핵심 maxes을합니다.

아래에서 볼 수 있듯이, 지금 Learnboost, Socket.io을 같은 사람에서 Cluster 모듈을 사용하고 있습니다.

나는 4 개 작업자 프로세스를 불 때, 와서 구독 각 브라우저 클라이언트는 레디 스에 게시 된 각 메시지의 4 개 복사본을 가져옵니다. 세 작업자 프로세스가있는 경우, 세 개의 사본이 있습니다.

나는 어떻게 든 cluster.js 파일에 레디 스 펍 / 하위 기능을 이동해야 같은데요.

Cluster.js

var cluster = require('./node_modules/cluster');

cluster('./app')
  .set('workers', 4)
  .use(cluster.logger('logs'))
  .use(cluster.stats())
  .use(cluster.pidfiles('pids'))
  .use(cluster.cli())
  .use(cluster.repl(8888))
  .listen(8000);

App.js

redis = require('redis'),
sys = require('sys');

var rc = redis.createClient();

var path = require('path')
  , connect = require('connect')
  , app = connect.createServer(connect.static(path.join(__dirname, '../')));

// require the new redis store
var sio = require('socket.io')
  , RedisStore = sio.RedisStore
  , io = sio.listen(app);

io.set('store', new RedisStore);io.sockets.on('connection', function(socket) {
    sys.log('ShowControl -- Socket connected: ' + socket.id);

    socket.on('channel', function(ch) {
        socket.join(ch)
        sys.log('ShowControl -- ' + socket.id + ' joined channel: ' + ch);
    });

    socket.on('disconnect', function() {
        console.log('ShowControll -- Socket disconnected: ' + socket.id);
    });
});

rc.psubscribe('showcontrol_*');

rc.on('pmessage', function(pat, ch, msg) {
    io.sockets.in(ch).emit('show_event', msg);
    sys.log('ShowControl -- Publish sent to channel: ' + ch);
});

// cluster compatiblity
if (!module.parent) {
  app.listen(process.argv[2] || 8081);
  console.log('Listening on ', app.address());
} else {
  module.exports = app;
}

client.html

<script src="http://localhost:8000/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script>
    var socket = io.connect('localhost:8000');
    socket.emit('channel', 'showcontrol_106');
    socket.on('show_event', function (msg) {
        console.log(msg);
        $("body").append('<br/>' + msg);
    });
</script>

해결법

  1. ==============================

    1.내가 클러스터 및 socket.io와 싸우고 있었어요. 때마다 내가 사용하는 클러스터 기능 I GET 많이 socket.io 성능 문제 및 문제 (필자는 비록 Nodejs 클러스터에 내장 사용하십시오).

    내가 클러스터 및 socket.io와 싸우고 있었어요. 때마다 내가 사용하는 클러스터 기능 I GET 많이 socket.io 성능 문제 및 문제 (필자는 비록 Nodejs 클러스터에 내장 사용하십시오).

    이 조회하는 동안, 나는 버그 리포트를 주위 파고와 socket.io의 자식에 비슷한 자신의 서버에 클러스터 또는 외부 부하 분산 장치를 사용하는 사람이 socket.io에 문제가있는 것 같다했습니다.

    당신이 자세한 로깅을 늘릴 경우 볼 문제 "하지 handshaken 클라이언트가 다시 연결해야 클라이언트"를 생성 할 것으로 보인다. 이 클러스터의 socket.io 실행이 내가이 다시 되돌아 생각 때문에 때마다 작정 나타납니다. 즉 클라이언트마다 클러스터 socket.io에 무작위 인스턴스에 연결됩니다 그것을 수행하는 새로운 연결 (이 권한을 부여 할 때 HTTP / 소켓 여러 / 플래시 연결을 수행하고 더 모든 시간 이후 때 새로운 데이터 폴링).

    지금은 내가 한 번에 1 socket.io 프로세스를 사용하여 다시 복귀했다, 이것은 버그가있을뿐만 아니라 socket.io가 구축되는 방법의 단점이 될 수 있습니다.

    추가 : 앞으로이 해결의 내 방법은 클라이언트 측에서 클러스터 다음 캐시 포트 선택 내부의 각 socket.io 인스턴스에 고유 한 포트를 할당하는 것입니다.

  2. ==============================

    2.턴이 Node.js를 / Socket.io 문제가 아닙니다 아웃, 난 그냥 그것에 대해 완전히 잘못된 방향으로 가고 있었다.

    턴이 Node.js를 / Socket.io 문제가 아닙니다 아웃, 난 그냥 그것에 대해 완전히 잘못된 방향으로 가고 있었다.

    뿐만 아니라 내가 노드 / 소켓 스택 외부에서 레디 스 서버에 게시하고, 나는 아직도 직접 레디 스 채널에 등록되었다. 술집 / 서브 상황의 양쪽에 나는 선 (善)은 "백 엔드에 레디 스 스토어와 Socket.io 클러스터"를 우회했다.

    그래서, 난 내 레일 응용 프로그램에서 메시지를 가져다가 socket.io-발표 모듈을 사용하여 Socket.io 방으로 그들을 '발표'(Node.js를 / Socket.io / Express와 함께) 약간의 응용 프로그램을 만들었습니다. 이제, Socket.io 라우팅 마법을 사용하여 각 노드 노동자는 얻을 것와 직접 연결 브라우저로 메시지를 보냅니다. 즉, 술집 및 하위 모두 이후 더 이상 중복 메시지는 Node.js를 / Socket.io 스택 내에서 일어났다.

    내 코드를 정리 취득 후 나는 github의의 어딘가에서 예를 넣을 수 있습니다.

  3. from https://stackoverflow.com/questions/8363242/im-receiving-duplicate-messages-in-my-clustered-node-js-socket-io-redis-pub-sub by cc-by-sa and MIT license