socket.io和websockets之间的差异

时间:2012-04-11 18:57:05

标签: node.js google-chrome firebug websocket socket.io

socket.io和websockets之间有什么区别     Node.js的?
它们都是服务器推送技术吗? 我感觉到的唯一区别是,

  1. socket.io允许我通过指定事件名称来发送/发送消息。

  2. 在socket.io的情况下,来自服务器的消息将到达所有客户端,但对于websockets中的相同内容,我被迫保留所有连接的数组并循环通过它以向所有客户端发送消息。

  3. 另外, 我想知道为什么网络检查员(如Chrome / firebug / fiddler)无法从服务器捕获这些消息(来自socket.io/websocket)?

    请澄清一下。

8 个答案:

答案 0 :(得分:409)

误解

关于WebSocket和Socket.IO,几乎没有什么常见的误解:

  1. 第一个误解是使用Socket.IO比使用WebSocket要容易得多,而WebSocket似乎并非如此。见下面的例子。

  2. 第二个误解是WebSocket在浏览器中没有得到广泛支持。有关详细信息,请参阅下文。

  3. 第三个误解是Socket.IO将连接降级为旧浏览器的后备。它实际上假设浏览器是旧的并且启动与服务器的AJAX连接,稍后在交换一些流量之后在支持WebSocket的浏览器上升级。有关详细信息,请参阅下文。

  4. 我的实验

    我写了一个npm模块来演示WebSocket和Socket.IO之间的区别:

    这是服务器端和客户端代码的简单示例 - 客户端使用WebSocket或Socket.IO连接到服务器,服务器以1s间隔发送三条消息,由客户端添加到DOM

    服务器侧

    比较使用WebSocket和Socket.IO的服务器端示例在Express.js应用程序中执行相同的操作:

    WebSocket服务器

    使用Express.js的WebSocket服务器示例:

    var path = require('path');
    var app = require('express')();
    var ws = require('express-ws')(app);
    app.get('/', (req, res) => {
      console.error('express connection');
      res.sendFile(path.join(__dirname, 'ws.html'));
    });
    app.ws('/', (s, req) => {
      console.error('websocket connection');
      for (var t = 0; t < 3; t++)
        setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
    });
    app.listen(3001, () => console.error('listening on http://localhost:3001/'));
    console.error('websocket example');
    

    来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js

    Socket.IO Server

    使用Express.js的Socket.IO服务器示例:

    var path = require('path');
    var app = require('express')();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    app.get('/', (req, res) => {
      console.error('express connection');
      res.sendFile(path.join(__dirname, 'si.html'));
    });
    io.on('connection', s => {
      console.error('socket.io connection');
      for (var t = 0; t < 3; t++)
        setTimeout(() => s.emit('message', 'message from server'), 1000*t);
    });
    http.listen(3002, () => console.error('listening on http://localhost:3002/'));
    console.error('socket.io example');
    

    来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js

    客户端

    比较使用WebSocket和Socket.IO在浏览器中执行相同操作的客户端示例:

    WebSocket客户端

    使用vanilla JavaScript的WebSocket客户端示例:

    var l = document.getElementById('l');
    var log = function (m) {
        var i = document.createElement('li');
        i.innerText = new Date().toISOString()+' '+m;
        l.appendChild(i);
    }
    log('opening websocket connection');
    var s = new WebSocket('ws://'+window.location.host+'/');
    s.addEventListener('error', function (m) { log("error"); });
    s.addEventListener('open', function (m) { log("websocket connection open"); });
    s.addEventListener('message', function (m) { log(m.data); });
    

    来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html

    Socket.IO客户端

    使用vanilla JavaScript的Socket.IO客户端示例:

    var l = document.getElementById('l');
    var log = function (m) {
        var i = document.createElement('li');
        i.innerText = new Date().toISOString()+' '+m;
        l.appendChild(i);
    }
    log('opening socket.io connection');
    var s = io();
    s.on('connect_error', function (m) { log("error"); });
    s.on('connect', function (m) { log("socket.io connection open"); });
    s.on('message', function (m) { log(m); });
    

    来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html

    网络流量

    要查看网络流量的差异,您可以run my test。以下是我得到的结果:

    WebSocket结果

    2个请求,1.50 KB,0.05 s

    从这2个请求中:

    1. HTML页面本身
    2. 连接升级到WebSocket
    3. (连接升级请求在具有101切换协议响应的开发人员工具上可见。)

      Socket.IO结果

      6个请求,181.56 KB,0.25 s

      根据这6项要求:

      1. HTML页面本身
      2. Socket.IO的JavaScript(180千字节)
      3. 首次长轮询AJAX请求
      4. 第二次长轮询AJAX请求
      5. 第三次长轮询AJAX请求
      6. 连接升级到WebSocket
      7. 截图

        我在localhost上获得的WebSocket结果:

        WebSocket results - websocket-vs-socket.io module

        我在localhost上获得的Socket.IO结果:

        Socket.IO results - websocket-vs-socket.io module

        自己测试

        快速入门:

        # Install:
        npm i -g websocket-vs-socket.io
        # Run the server:
        websocket-vs-socket.io
        

        在浏览器中打开http://localhost:3001/,使用Shift + Ctrl + I打开开发人员工具,打开网络选项卡,然后使用Ctrl + R重新加载页面以查看WebSocket版本的网络流量。

        在浏览器中打开http://localhost:3002/,使用Shift + Ctrl + I打开开发人员工具,打开网络选项卡,然后使用Ctrl + R重新加载页面以查看Socket.IO版本的网络流量。

        要卸载:

        # Uninstall:
        npm rm -g websocket-vs-socket.io
        

        浏览器兼容性

        截至2016年6月,WebSocket适用于除Opera Mini以外的所有内容,包括高于9的IE。

        截至2016年6月,这是Can I Use上WebSocket的浏览器兼容性:

        enter image description here

        请参阅http://caniuse.com/websockets了解最新信息。

答案 1 :(得分:291)

它的优点在于它简化了#2中描述的WebSockets的使用,并且可能更重要的是,它在浏览器或服务器不支持WebSockets的情况下为其他协议提供故障转移。我会避免直接使用WebSockets,除非您非常熟悉它们不起作用的环境,并且您能够解决这些限制。

这是对WebSockets和Socket.IO的好读。

http://davidwalsh.name/websocket

答案 2 :(得分:26)

我将提供反对使用socket.io的论据。

我认为使用socket.io只是因为它有后备不是一个好主意。让IE8 RIP。

过去有很多新版本的NodeJS破坏了socket.io。您可以查看这些列表中的示例...... https://github.com/socketio/socket.io/issues?q=install+error

如果您要开发Android应用程序或需要使用现有应用程序的东西,您可能会立即使用WS,socket.io可能会给您带来一些麻烦......

另外,Node.JS的WS模块使用起来非常简单。

答案 3 :(得分:18)

使用Socket.IO基本上就像使用jQuery一样 - 您希望支持较旧的浏览器,您需要编写更少的代码,并且库将提供回退。 Socket.io使用websockets技术(如果可用),如果没有,则检查可用的最佳通信类型并使用它。

答案 4 :(得分:13)

tl; dr;

比较它们就像将餐厅食物(有时可能很贵,也许不是您想要的100%)与自制食物进行比较,在这里您必须收集并种植每种食物自己的成分之一。

也许如果您只想吃一个苹果,那么后者会更好。但是,如果您想要复杂的东西而一个人呆着,那真的不值得自己做饭和制作所有食材。


我都处理过这两个。这是我的经验。

SocketIO

  • 具有自动连接

  • 具有名称空间

  • 有房间

  • 具有订阅服务

  • 具有预先设计的通信协议

    (谈论订阅,取消订阅或向特定房间发送消息的协议,您都必须在网络套接字中自行设计)

  • 具有良好的日志记录支持

  • 已与Redis等服务集成

  • 在不支持WS的情况下具有后备功能(当然,这种情况越来越少)

  • 这是一个图书馆。这意味着,它实际上在各方面帮助您的事业。 Websockets是SocketIO始终使用的协议,而不是库。

  • 整个架构是由不是您的人支持和设计的,因此您不必花时间设计和实现上述内容,而您可以直接编写业务规则。

  • 有一个社区,因为它是一个库(您不能拥有HTTP或Websockets的社区:P它们只是标准/协议)

Websockets

  • 您拥有绝对的控制权,具体取决于您是谁,这可能是好事也可能是坏事
  • 轻巧(记住,它是协议,而不是库)
  • 您设计自己的体系结构和协议
  • 没有自动连接,您可以自行实现
  • 没有订阅服务,您可以自行设计
  • 没有日志记录,您可以实现
  • 没有后备支持
  • 没有房间或名称空间。如果您想要这样的概念,则可以自己实现它们
  • 什么都不支持,您将成为实现一切的人
  • 首先,您必须专注于技术部分,并设计Websocket往返的所有内容
  • 您必须首先调试设计,这将花费很长时间

很显然,您可以看到我对SocketIO有偏见。我想这么说,但是我真的不是。

我真的在争取不使用SocketIO 。我不想使用它。我喜欢自己设计东西,自己解决问题。 但是,如果您想要开展一项业务,而不仅仅是一个1000行的项目,并且要选择Websockets,则必须自己实现每件事。您必须调试所有内容。您必须制作自己的订阅服务。您自己的协议。你自己的一切。而且您必须确保所有内容都非常复杂。而且您在此过程中会犯很多错误。您将花费大量时间来设计和调试所有内容。我做到了,现在仍然做。 我正在使用websockets ,原因是对于一个试图解决其创业公司业务规则而不是Websocket设计术语的人来说,它们是无法忍受的。

如果您是一支单兵或一小队,则为大型应用程序选择Websocket并不是一个容易的选择。与以前使用SocketIO编写的代码相比,我在Websockets中编写的代码更多,而我要说的是... 如果您想要成品和设计,请选择SocketIO。(除非您想要功能上非常简单的东西)

答案 5 :(得分:6)

https://socket.io/docs/#What-Socket-IO-is-not(带有我的重点

什么不是Socket.IO

Socket.IO 不是是WebSocket实现。尽管Socket.IO确实确实在可能的情况下使用WebSocket作为传输工具,但是它在每个数据包中添加了一些元数据:当需要消息确认时,数据包类型,名称空间和数据包ID。这就是为什么 WebSocket客户端不能能够成功连接到Socket.IO服务器,而 Socket.IO客户端将不能 strong>能够连接到WebSocket服务器。请参阅协议规范here

// WARNING: the client will NOT be able to connect!
const client = io('ws://echo.websocket.org');

答案 6 :(得分:3)

Socket.IO使用WebSocket,当WebSocket不可用时,使用后备算法进行实时连接。

答案 7 :(得分:1)

即使现代浏览器现在支持WebSocket,我也认为没有必要丢弃SocketIO,并且它在当今的任何项目中都占有一席之地。这很容易理解,而且我个人通过SocketIO学会了WebSockets的工作方式。

如本主题所述,有很多用于Angular,React等的集成库以及用于TypeScript和其他编程语言的定义类型。

我要添加到Socket.io和WebSockets之间的区别的另一点是,使用Socket.io进行群集并不是什么大问题。 Socket.io提供Adapters,可用于将其与Redis链接以增强可伸缩性。例如,您有ioredissocket.io-redis

是的,我知道SocketCluster存在,但这是题外话。