Node.js的速度困境:AJAX 和 Socket.IO到底选哪个?

Posted 充实的脑洞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js的速度困境:AJAX 和 Socket.IO到底选哪个?相关的知识,希望对你有一定的参考价值。

点击"充实的脑洞"关注我! 


翻译:疯狂的技术宅 原文标题:A Node.js speed dilemma: AJAX or Socket.IO? 原文链接:http://www.cubrid.org/blog/nodejs-speed-dilemma-ajax-or-socket-io

当我开始自己的第一个Node.js项目时,我发现的第一件事就是如何处理浏览器(客户端)和中间件之间的通信(中间件是用CUBRID Node.js驱动编写的(node-cubrid)的Node.js应用与CUBRID 8.4.1数据库交换信息)。

我已经非常熟悉AJAX了,但是在学习Node.js时,我发现了Socket.IO模块,甚至在互联网上发现了一些非常不错的代码示例... 非常好用(重用)...

因此,这很快成为一个难题:应该选哪个,Ajax还是sockets.io?

显然,由于我的经验非常有限,所以我需要更多的信息。换句话说,应该好好的Google一番 :)

显然相关的信息非常多,但是需要过滤掉那些没用的 "噪音",并得到真正有用的东西。让我跟大家分享一下关于这个话题的一些链接:

  • http://stackoverflow.com/questions/7193033/nodejs-ajax-vs-socket-io-pros-and-cons

  • http://podefr.tumblr.com/post/22553968711/an-innovative-way-to-replace-ajax-and-jsonp-using

  • http://stackoverflow.com/questions/4848642/what-is-the-disadvantage-of-using-websocket-socket-io-where-ajax-will-do?rq=1

  • http://howtonode.org/websockets-socketio

总而言之,这是我很快发现的:

  1. Socket.IO(通常)用的是客户端和服务器(中间件)之间的长连接,因此你会达到服务器端资源所允许的并发连接数上限(而相同的资源可以支持更多的AJAX异步请求)。

  2. 使用AJAX,你可以请求RESTful接口。这意味着您可以利用现有的 HTTP 服务,例如:代理缓存请求和带条件的GET请求。

  3. 与 Socket.IO 相比,AJAX 有更多(通信)数据开销(例如:HTTP头,Cookie等)。

  4. AJAX通常比Socket.IO快 ...

  5. 当使用Socket.IO时,可以进行双向通信,其中每一方——客户端或服务器都可以发起请求。在AJAX中,只有客户才能发起请求!

  6. Socket.IO有更多的传输选项,包括Adobe Flash。

现在,对于我自己的应用,我最感兴趣的是发起请求并从(Node.js)服务器获取数据的速度!

关于与CUBRID数据库中间件的数据通信,因为大约90%的数据访问是只读的,一个好的数据缓存机制显然是一个不错的途径!但关于这个,我下次再谈。

所以我决定对他们的(Ajax和socket)速度进行测试,看看哪一个更快(至少在我的硬件和软件环境下)!我的硬件环境是:i5处理器,8GB内存和英特尔X25 SSD硬盘。

但是严格来说,任何性能测试都取决于您的硬件和软件配置,在你自己的环境中去测试终归是一个好主意,不要过于依赖你在互联网上找到的各种信息,更多的问题需要你自己去发现!

我要做的测试需要满足以下要求:

  • 测试:

  • AJAX

  • Socket.IO 持续连接模式

  • Socket.IO 非持续链接模式

  • 测试客户端与服务器之间进行10、100,、250、500条数据交换时的情况

  • 中间件服务器(Node.js Web 服务器)和客户端(浏览器)之间交换的每条数据都是一个4KBytes的随机数据串

  • 在 release(非调试)模式下运行服务器

  • 用Firefox作为客户端

  • 最小化控制台消息输出,不管是服务器端还是客户端

  • 在客户端页面硬性重新加载后进行每个测试

  • 每次测试至少重复3次,以确保结果一致

测试Socket.IO,使用持久连接

我创建了一小型的小Node.js服务器,用它处理客户端请求:

 
   
   
 
  1. io.sockets.on('connection', function (client) {

  2.    client.on('send_me_data', function (idx) {

  3.        client.emit('you_have_data', idx, random_string(4096));

  4.    });

  5. });

这是我用于测试的JS客户端脚本:

 
   
   
 
  1. var socket = io.connect(document.location.href);

  2. socket.on('you_have_data', function (idx, data) {

  3.    var end_time = new Date();

  4.    total_time += end_time - start_time;

  5.    logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');

  6.    if (idx++ < countMax) {

  7.        setTimeout(function () {

  8.            start_time = new Date();

  9.            socket.emit('send_me_data', idx);

  10.        }, 500);

  11.    }

  12. });

测试Socket.IO,使用非持久连接

这次,对于每次数据交换,我都打开一个新的socket-io连接。

Node.js服务器代码与上一个类似,但是我决定在连接之后立即发送客户端数据,因为每次数据交换都会启动一个新的连接:

 
   
   
 
  1. io.sockets.on('connection', function (client) {

  2.    client.emit('you_have_data', random_string(4096));

  3. });

客户端测试代码:

 
   
   
 
  1. function exchange(idx) {

  2.    var start_time = new Date();

  3.    var socket = io.connect(document.location.href, {'force new connection' : true});

  4.    socket.on('you_have_data', function (data) {

  5.        var end_time = new Date();

  6.        total_time += end_time - start_time;

  7.        socket.removeAllListeners();

  8.        socket.disconnect();

  9.        logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');

  10.        if (idx++ < countMax) {

  11.            setTimeout(function () {

  12.                exchange(idx);

  13.            }, 500);

  14.        }

  15.    });

  16. }

测试AJAX

最后是AJAX测试...

Node.js服务器代码与以前的代码不同:

 
   
   
 
  1. res.writeHead(200, {'Content-Type' : 'text/plain'});

  2. res.end('_testcb(\'{"message": "' + random_string(4096) + '"}\')');

至于客户端代码,这是我以前测试的:

 
   
   
 
  1. function exchange(idx) {

  2.    var start_time = new Date();

  3.    $.ajax({

  4.        url : 'http://localhost:8080/',

  5.        dataType : "jsonp",

  6.        jsonpCallback : "_testcb",

  7.        timeout : 300,

  8.        success : function (data) {

  9.            var end_time = new Date();

  10.            total_time += end_time - start_time;

  11.            logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.');

  12.            if (idx++ < countMax) {

  13.                setTimeout(function () {

  14.                    exchange(idx);

  15.                }, 500);

  16.            }

  17.        },

  18.        error : function (jqXHR, textStatus, errorThrown) {

  19.            alert('Error: ' + textStatus + " " + errorThrown);

  20.        }

  21.    });

  22. }

记住,当将AJAX和Node.js一起编码时,你需要考虑到可能的跨域请求和同源策略,因此应该使用基于JSONP的格式!

顺便说一句,可以看到,我仅引用了测试代码中最重要的部分,以节省篇幅。如果有人需要完整的服务器和客户端代码,请告诉我 - 我很乐意分享。

好的 - 现在看看完成这些工作后我们得到了什么!

我分别运行了10、100、250和500个数据交换的测试,这是最终测试结果:

Data exchanges Socket.IO NON-persistent (ms.) AJAX (ms.) Socket.IO persistent (ms.)
10 90 40 32
100 900 320 340
250 2,400 800 830
500 4,900 1,500 1,600

看看结果,我们会注意一些情况:

  1. 对于每种类型的测试,结果遵循线性增长的规律,这很好——表明结果是一致的。

  2. 结果清楚地表明,当使用Socket.IO非持久性连接时,性能数字比其他数据差得多。

  3. 在AJAX和Socket.IO持久连接之间似乎并没有太大区别——我们只谈几毫秒的差异。 这意味着,如果您每天的数据交换次数不超过10,000次的话,用户基本上不会注意到速度差异...

下图描述了在测试中获得的数字:

那么接下来呢?

嗯,我必须弄清楚自己需要支持什么样的流量,然后我将重新运行这些测试,但这次不包括Socket.IO非持久连接。因为很明显,我需要在AJAX和持久的Socket.IO连接之间进行选择。

而且我也了解到,最有可能的是,速度差异不会像人们想象的那样大,至少不是为了一个“小流量”的网站,所以我在确定自己的解决方案时,还需要研究每个方法/技术的其他优缺点!

ps. 这里有一些资源,可以找到关于Node.js、Socket.IO 和 AJAX 的一些有趣的东西:

  • http://socket.io/#how-to-use

  • http://www.hacksparrow.com/jquery-with-node-js.html

  • http://www.slideshare.net/toddeichel/nodejs-talk-at-jquery-pittsburgh

  • http://tech.burningbird.net/article/node-references-and-resources

  • http://davidwalsh.name/websocket


----------充实的脑洞----------

长按二维码关注充实的脑洞,睡前给你看一些有意思的东西。




以上是关于Node.js的速度困境:AJAX 和 Socket.IO到底选哪个?的主要内容,如果未能解决你的问题,请参考以下文章

Socket.IO 对 Node.js 有啥作用

01 . 部署Node.js项目

01 . 部署Node.js项目

Node.js, Ajax 发送和接收 Json

使用 node.js 和 express 的 JQuery Ajax 发布请求

使用 Ajax 和 Node.js 的简单按钮单击示例?