我的聊天工作在24个线程(2x 6核X5650 @ 2.67GHz)...如果有大约1000个连接CPU使用率(在每个线程上)增长到80-100%....我认为有些东西是我的代码错了...节点不应该只用1000个连接生成这样的负载。你能不能给我一些关于在哪里看看的想法
我的代码:
express = require('express')
http = require('http');
cluster = require("cluster");
numCPUs = require("os").cpus().length,
port = 55678;
userCount = 0;
interv = false;
RedisStore = require("socket.io/lib/stores/redis"),
redis = require("socket.io/node_modules/redis"),
pub = redis.createClient(),
sub = redis.createClient(),
client = redis.createClient(),
counter = redis.createClient();
counter.set('count',0);
client.set('searching',0);
client.del('freeusers');
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
}
else
{
app = express();
server = http.createServer(app).listen(port);
io = require('socket.io').listen(server);
io.configure(function () {
// io.set("transports", ["websocket"])
io.set("store", new RedisStore({
redisPub: pub,
redisSub: sub,
redisClient: client
})
);
io.set('log level', 0);
io.enable('browser client minification');
io.enable('browser client etag');
io.enable('browser client gzip');
});
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.php');
});
io.sockets.on('connection', function (socket){
var address = socket.handshake.address;
socket.set('options', JSON.stringify({'sex':'male','seek':'both'}));
socket.set('partner', 5);
socket.set('ip', address.address);
socket.emit('setsocket',socket.id);
counter.incr('count', function(err, newId){
userCount = newId;
socket.emit('people', userCount);
socket.broadcast.emit('people', userCount);
// console.log(Date(Date.now()) + ' Connected User ('+socket.id+' | '+address.address+':'+address.port+') '+userCount);
});
socket.ip = address.address;
socket.on('syscmd', function(cmd){
switch (cmd.cmd){
case 'new':
socket.set('options', JSON.stringify({'sex':cmd.sex,'seek':cmd.seek}));
socket.emit('updatechat', 'Poszukujemy dla Ciebie obcego, poczekaj ...');
socket.emit('setflag',1);
addNewUser(socket.id);
lookforpartner(socket.id);
break;
case 'reconnect':
socket.set('options', JSON.stringify({'sex':cmd.sex,'seek':cmd.seek}));
socket.get('partner', function(err, partner){
stopchat(socket.id,partner);
socket.emit('updatechat', 'Poszukujemy dla Ciebie obcego, poczekaj ...');
socket.emit('setflag',1);
addNewUser(socket.id);
lookforpartner(socket.id);
});
break;
default:
}
});
socket.on('sexchange', function (sex) {
socket.get('options',function(err,options){
socket.set('options', JSON.stringify({'sex':sex,'seek':options.seek}));
});
});
socket.on('seekchange', function (seek) {
socket.get('options',function(err,options){
socket.set('options', JSON.stringify({'sex':options.sex,'seek':seek}));
});
});
socket.on('updatechat', function(data){
socket.get('partner', function(err, partner) {
io.sockets.socket(partner).emit('updatechat',data);
});
socket.emit('updatechat',data);
});
socket.on('msgchat', function (data) {
socket.get('partner', function(err, partner) {
io.sockets.socket(partner).emit('msgchat',socket.id,data);
// console.log('Message between: '+socket.id+ ' AND '+partner+': '+data);
});
socket.emit('msgchat',socket.id , data);
});
socket.on('typing', function (data) {
socket.get('partner', function(err, partner){
io.sockets.socket(partner).emit('typing');
});
});
socket.on('stoptyping', function (data) {
socket.get('partner', function(err, partner){
io.sockets.socket(partner).emit('stoptyping');
});
});
socket.on('disconnect', function(){
var address = socket.handshake.address;
socket.get('partner', function(err, partner){
stopchat(socket.id,partner)
counter.decr('count', function(err, newId){
userCount = newId;
socket.broadcast.emit('people', userCount);
// console.log(Date(Date.now()) + ' Disconnected User ('+socket.id+' | '+address.address+':'+address.port+') '+userCount);
});
});
});
function removeUser(id)
{
client.srem('freeusers',id);
}
function addNewUser(id)
{
removeUser(id);
client.sadd('freeusers',id);
}
function lookforpartner(id)
{
// console.log('('+id+') searching ...')
client.get('searching',function(error,result){
if(parseInt(result) == 1)
{
return true;
}
else
{
client.smembers('freeusers',function(error,freeusers){
if(freeusers.length > 1)
{
client.set('searching',1);
partner = freeusers[Math.floor(Math.random()*freeusers.length)];
while(partner == id)
{
partner = freeusers[Math.floor(Math.random()*freeusers.length)];
}
socket.get('options',function(err,options){
options = JSON.parse(options);
if(err || options == null || typeof options != 'object' || !options.hasOwnProperty('seek') || !options.hasOwnProperty('sex'))
{
client.set('searching',0);
return false;
}
// console.log('partner: '+id+' (sex:'+options.sex+' and seek:'+options.seek+')');
io.sockets.socket(partner).get('options',function(err,poptions){
poptions = JSON.parse(poptions);
if(err || options == null || typeof poptions != 'object' || !poptions.hasOwnProperty('seek') || !poptions.hasOwnProperty('sex'))
{
removeGhost(partner);
client.set('searching',0);
return false;
}
// console.log('partner: '+partner+' (sex:'+poptions.sex+' and seek:'+poptions.seek+')');
if((options.seek == poptions.sex || options.seek == 'both') && (poptions.seek == options.sex || poptions.seek == 'both'))
{
// console.log('parred: '+partner+' (sex:'+poptions.sex+' and seek:'+poptions.seek+') AND '+id+' (sex:'+options.sex+' and seek:'+options.seek+')');
removeUser(partner);
removeUser(id);
io.sockets.socket(id).set('partner', partner);
io.sockets.socket(partner).set('partner', id);
io.sockets.socket(id).emit('chatunblock',1);
io.sockets.socket(partner).emit('chatunblock',1);
io.sockets.socket(id).emit('updatechat', 'Obcy podłączony, napisz Cześć :-)');
io.sockets.socket(partner).emit('updatechat', 'Obcy podłączony, napisz Cześć :-)');
}
client.set('searching',0);
});
});
}
});
}
});
}
function removeGhost(id)
{
console.log('Removing ghost: '+id);
removeUser(id);
io.sockets.socket(id).set('partner', 5);
io.sockets.socket(id).emit('disconnected','end');
}
function stopchat(id,partner)
{
removeUser(id);
if(partner != 5)
{
socket.set('partner', 5);
io.sockets.socket(partner).set('partner', 5);
io.sockets.socket(partner).emit('updatechat', 'Obcy wyszedł :-(');
io.sockets.socket(partner).emit('disconnected','end');
}
io.sockets.socket(id).emit('disconnected',2);
}
});
}