socket.io emit 的性能问题,求大神解答
发布于 8 年前 作者 liumoujie 6151 次浏览 来自 问答

不用多说,直接上代码。 直接使用 net 包,进行数据发送 ================== net socket server ==================== const net = require(‘net’); //net socket server code var connections = [] const server = net.createServer(© => { c.on(‘end’, () => { console.log(‘client disconnected’); }); connections[connections.length] = c; c.on(‘data’, function (data) { // when got data from client, then send data to all connect for (var i in connections) { connections[i].write(i + ’ iii firstRsp\r\n’); } }); }); ================ net socket client code ===================== const net = require(‘net’); var sockets = [];

const argparse_1 = require(“argparse”); let parser = new argparse_1.ArgumentParser({ version: ‘1.0’, addHelp: true, description: ‘PTT server benchmarking’ });

parser.addArgument([’-a’, ‘–amout’], {help: ‘total users will login’, required: true});

var option = parser.parseArgs(process.argv.slice(2));

var cmp = 0; var rmcmp = 0; var len = option.amout || 100;

var st = Date.now(); var nottime = 0;

for (var i = 0; i < len; i++) { sockets[i] = net.connect(8124, “localhost”); (function (i) { sockets[i].on(‘connect’, function () { ////console.log(’----------connected------------’); //sockets[i].write(‘first\r\n’); cmp++; if (cmp == len) { nottime = Date.now(); console.log(’---------- all connected------------’ + (nottime - st)); for (var obj in sockets) { (function (obj) { sockets[obj].write(‘roomid\r\r’); })(obj); } } });

    sockets[i].on('error', function (err) {
        //console.log(err);
    })

    sockets[i].on('data', (data)=> {
        rmcmp++;
        //console.log(rmcmp + "-----" + data.toString());
        if (rmcmp == 100000) {
            console.log('---------- 100000 times complete ------------' + (Date.now() - nottime))
        }
    });
})
(i);
}

执行结果,500 个连接,100000 客户端与服务器端的交互,只需要 1000ms左右每ms可以达到 90 次交互。
但是,如果采用 socket.io 
=====================    server code  ========================
var express = require('express');

var app = express(); var server = require(‘http’).createServer(app); var io = require(‘socket.io’)(server, {‘transports’: [‘polling’], allowUpgrades: false}); var redis = require(‘socket.io-redis’); //var sticky = require(‘sticky-session’);

var port = process.env.PORT || 3000;

// Routing app.use(express.static(__dirname + ‘/public’));

server.listen(port, function () { console.log(‘Server listening at port %d’, port); });

var st = Date.now(); var time = 0;

io.on(‘connect’, function (socket) { //console.log("current socket work on proccess : " + cluster.worker.id); socket.on(‘first’, function (data) { socket.emit(‘firstRsp’, Date.now() + ’ has got you message. ’ + data, {mask: false}); });

socket.on('roomid', function (data) {
    //console.log("roomid", data);
    socket.join('room', function () {
        socket.to('room').emit('roomid', data + ' joined ', {mask: false});
    });

});
socket.on('single', function (data) {
    console.log('-server has got your data-' + data);
});

socket.on('disconnect', function () {
    socket.leave('roomid');
    //console.log(socket.id + ' leave');
})

}); ================== socket.io client code ================== var io = require(‘socket.io-client’); var sockets = []

const argparse_1 = require(“argparse”); let parser = new argparse_1.ArgumentParser({ version: ‘1.0’, addHelp: true, description: ‘PTT server benchmarking’ });

parser.addArgument([’-a’, ‘–amout’], {help: ‘total users will login’, required: true});

var option = parser.parseArgs(process.argv.slice(2));

var st = Date.now();

var cmp = 0; var rmcmp = 0; var len = option.amout || 100;

var cur = 0; var total = 0; for (var i = 0; i < len; i++) { for (var j = 0; j < i; j++) { total++; } }

for (var i = 0; i < len; i++) {

sockets[i] = io('http://localhost:3000', {'transports': ['polling'], allowUpgrades: false});
(function (i) {
    sockets[i].on('connect', function () {
        ////console.log('----------connected------------');
        //sockets[i].emit('first', ' first ' + i);

        cmp++;
        ////console.log(data);
        if (cmp == len) {
            cur = Date.now();
            console.log("total use:" + (cur - st));
            for (var obj in sockets) {
                (function (obj) {
                    sockets[obj].emit('roomid', " iam " + obj, {mask: false});
                })(obj);
            }
        }

    });

    sockets[i].on('error', function (err) {
        //console.log(err);
    })

    sockets[i].on('s_login_failed', (err)=> {
        console.log(JSON.stringify(err));
    });

    sockets[i].on('roomid', function (data) {
        rmcmp++;
        //console.log(i + " get data " + rmcmp + " times. " + data + "    " + (Date.now() - st) + " to:" + total);
        if (rmcmp == total) {
            console.log(" complete " + total + " times total use time : " + (Date.now() - cur));
        }
    })

    sockets[i].on('firstRsp', function (data) {
        //console.log(data);
        //sockets[i].emit('roomid', " iam " + i);
        cmp++;
        ////console.log(data);
        if (cmp == len) {
            cur = Date.now();
            console.log("total use:" + (cur - st));
            for (var obj in sockets) {
                (function (obj) {
                    sockets[obj].emit('room', " iam " + obj);
                })(obj);
            }
        }
    });
    sockets[i].on('disconnect', function () {
    })
})
(i);

} 测试结果,通知 44850 次,需要 1869ms 左右,一ms 只能达到 23 次左右。 我的问题是: socket.io是否能达到直接使用net包的每ms 90次左右的数据发送,可以如何做,不可以,为什么?

10 回复

@TimothyJin 你的意义是协议决定了socket.io天生就要慢5倍?

net.socket和socket.io之间关系, net.socket操作tcp, 往上的http基于tcp, http再往上就是不同浏览器了, socket.io分拆出的engine.io就是基于各种transports解决不同浏览器类似websocket双向通讯需求兼容的包, 再往上的socket.io是基于engine.io的一系列约定俗成的通用业务封装.

websocket 是层协议 -> engine.io 有层协议-> socket.io 又是层协议… websocket 性能测试就不好做, 更别说 socket.io 了… 还是等高人来答…

@TimothyJin http和tcp 以及 websocket 和 http 之间的关系又是什么?

@yjhjstz node --prof 导入log文件之后,再用webstorm的V8分析工具分析,显示 emit 使用 cpu 高达 100%

能发我看下吗?毕竟emit 是回调的入口 @liumoujie

@yjhjstz 代码全部都贴出来了,就在上面。

profiler的文件呢

回到顶部