2016-11-30 87 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'); 
});