Używam Node.js, Socket.io z Redisstore, Cluster od użytkowników Socket.io i Redis.Otrzymuję zduplikowane wiadomości w mojej klastrowej aplikacji node.js/socket.io/redis pub/sub
Posiadam aplikację pub/sub, która działa dobrze tylko na jednym węźle Node.js. Ale, gdy jest pod dużym obciążeniem, maksymalizuje tylko jeden rdzeń serwera, ponieważ Node.js nie jest napisany dla maszyn wielordzeniowych.
Jak widać poniżej, teraz używam modułu Cluster od LearnBoost, tych samych osób, które tworzą Socket.io.
Ale kiedy uruchamiam 4 procesy robocze, każdy klient przeglądarki, który wchodzi i subskrybuje, otrzymuje 4 kopie każdej wiadomości opublikowanej w Redis. Jeśli istnieją trzy procesy robocze, istnieją trzy kopie.
Zgaduję, że muszę przenieść funkcje pub/sub redis do pliku cluster.js w jakiś sposób.
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>
Czy możesz napisać, co zrobiłeś, aby rozwiązać ten problem? –
Możesz zobaczyć, co tutaj zrobiliśmy: https://github.com/StageIt/redis Jednak przywróciliśmy go do jednego węzła z powodu błędu w pliku socket.io. Oto omówienie tego błędu, może to być już naprawione: https://github.com/LearnBoost/socket.io/issues/438#issuecomment-3371390 – messick