2016-11-30 86 views
1

我想學習node.js羣集與socket.io創建一個聊天應用程序...問題是,我似乎無法讓事情工作。使用node.js羣集與socket.io聊天應用程序

我一直試圖去通過所有的教程包括一個我從這個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'); 
});