2016-11-30 2 views
1

Я пытаюсь изучить node.js-кластер с socket.io для создания чат-приложения ... проблема в том, что я не могу заставить работать.use node.js кластер с приложением socket.io chat

я пытался пройти через все учебники в том числе тот, который я получаю от этого http://stackoverflow.com/questions/18310635/scaling-socket-io-to-multiple-node-js-processes-using-cluster/18650183#18650183

, когда я пытаюсь открыть два браузера, сообщения не идут на другой браузер.

вот код, который я получил

var express = require('express'), 
 
    cluster = require('cluster'), 
 
    net = require('net'), 
 
    socketio = require('socket.io'), 
 
    socket_redis = require('socket.io-redis'); 
 

 
var port = 3000, 
 
    num_processes = require('os').cpus().length; 
 

 
if (cluster.isMaster) { 
 
    // This stores our workers. We need to keep them to be able to reference 
 
    // them based on source IP address. It's also useful for auto-restart, 
 
    // for example. 
 
    var workers = []; 
 

 
    // Helper function for spawning worker at index 'i'. 
 
    var spawn = function(i) { 
 
     workers[i] = cluster.fork(); 
 

 
     // Optional: Restart worker on exit 
 
     workers[i].on('exit', function(code, signal) { 
 
      console.log('respawning worker', i); 
 
      spawn(i); 
 
     }); 
 
    }; 
 

 
    // Spawn workers. 
 
    for (var i = 0; i < num_processes; i++) { 
 
     spawn(i); 
 
    } 
 

 
    // Helper function for getting a worker index based on IP address. 
 
    // This is a hot path so it should be really fast. The way it works 
 
    // is by converting the IP address to a number by removing non numeric 
 
    // characters, then compressing it to the number of slots we have. 
 
    // 
 
    // Compared against "real" hashing (from the sticky-session code) and 
 
    // "real" IP number conversion, this function is on par in terms of 
 
    // worker index distribution only much faster. 
 
    var worker_index = function(ip, len) { 
 
     var s = ''; 
 
     for (var i = 0, _len = ip.length; i < _len; i++) { 
 
      if (!isNaN(ip[i])) { 
 
       s += ip[i]; 
 
      } 
 
     } 
 

 
     return Number(s) % len; 
 
    }; 
 

 
    // Create the outside facing server listening on our port. 
 
    var server = net.createServer({ pauseOnConnect: true }, function(connection) { 
 
     // We received a connection and need to pass it to the appropriate 
 
     // worker. Get the worker for this connection's source IP and pass 
 
     // it the connection. 
 
     var worker = workers[worker_index(connection.remoteAddress, num_processes)]; 
 
     worker.send('sticky-session:connection', connection); 
 
    }).listen(port); 
 
} else { 
 
    // Note we don't use a port here because the master listens on it for us. 
 
    var app = new express(); 
 

 
    // Here you might use middleware, attach routes, etc. 
 
    app.use('/assets', express.static(__dirname +'/public')); 
 
    app.get('/', function(req, res){ 
 
     res.sendFile(__dirname + '/index.html'); 
 
    }); 
 

 

 
    // Don't expose our internal server to the outside. 
 
    var server = app.listen(), 
 
     io = socketio(server); 
 

 
    // Tell Socket.IO to use the redis adapter. By default, the redis 
 
    // server is assumed to be on localhost:6379. You don't have to 
 
    // specify them explicitly unless you want to change them. 
 
    io.adapter(socket_redis({ host: 'localhost', port: 6379 })); 
 

 
    // Here you might use Socket.IO middleware for authorization etc. 
 

 
    io.on('connection', function(socket) { 
 
     console.log('New client connection detected on process ' + process.pid); 
 

 
     socket.emit('welcome', {message: 'Welcome to BlueFrog Chat Room'}); 
 
     socket.on('new.message', function(message) { 
 
      socket.emit('new.message', message); 
 
     }) 
 

 
    }); 
 

 

 
    // Listen to messages sent from the master. Ignore everything else. 
 
    process.on('message', function(message, connection) { 
 
     if (message !== 'sticky-session:connection') { 
 
      return; 
 
     } 
 

 
     // Emulate a connection event on the server by emitting the 
 
     // event with the connection the master sent us. 
 
     server.emit('connection', connection); 
 

 
     connection.resume(); 
 
    }); 
 
}

+0

Что не работает? что вы пробовали? в чем проблема? – xShirase

+0

Сообщения, которые я отправляю из браузера, доходят до моего сервера, и само сообщение возвращается в тот же браузер, но не публикуется в другом браузере ... Я думаю, что это имеет какое-то отношение к выпуску, я не знаю. – cabs

ответ

1

Если я правильно понимаю, ваша проблема в том, что сообщения от клиента не транслируется на других клиентов. вы можете легко решить эту проблему:

io.on('connection', function(socket) { 
    console.log('New client connection detected on process ' + process.pid); 

    socket.emit('welcome', {message: 'Welcome to BlueFrog Chat Room'}); 
    socket.on('new.message', function(message) { 
     socket.emit('new.message', message); // this line sends the message back to the emitter 
     socket.broadcast.emit('my message', msg); // this broadcasts the message to all the clients 
    }) 

}); 
1

Есть разные способы испускать сообщение. Тот, который вы используете, выдает сообщение только в сокет, который сначала отправил сообщение «new.message» на сервер. Это означает, что сокет получит сообщение, которое вы испускаете там, только если оно сначала отправило сообщение «new.message». Вот почему в вашем браузере клиент, получающий сообщение, является единственным, кто его получает.

Изменить это:

socket.on('new.message', function(message) { 
     io.sockets.emit('new.message', message);//use this if even the browser originating the message should be updated. 
     socket.broadcast.emit('new.message', message);//use this if everyone should be updated excpet the browser source of the message. 
    }) 

Вот различные способы, которыми Вы можете испускают:

io.sockets.on('connection', function(socket) { 
    //This message is only sent to the client corresponding to this socket. 
    socket.emit('private message', 'only you can see this'); 

    //This message is sent to every single socket connected in this 
    //session, including this very socket. 
    io.sockets.emit('public message', 'everyone sees this'); 

    //This message is sent to every single connected socket, except 
    //this very one (the one requesting the message to be broadcasted). 
    socket.broadcast.emit('exclude sender', 'one client wanted all of you to see this'); 
}); 

Вы также можете добавить сокеты в разные комнаты, когда они соединяются так, что вы только общаться сообщения с сокетами из данного помещения:

io.sockets.on('connection', function(socket) { 
    //Add this socket to a room called 'room 1'. 
    socket.join('room 1'); 

    //This message is received by every socket that has joined 
    //'room 1', including this one. (Note that a socket doesn't 
    //necessarily need to belong to a certain room to be able to 
    //request messages to be sent to that room). 
    io.to('room 1').emit('room message', 'everyone in room 1 sees this'); 

    //This message is received by every socket that has joined 
    //'room 1', except this one. 
    socket.broadcast.to('room 1').emit('room message', 'everyone in room 1 sees this'); 
}); 
Смежные вопросы