【问题标题】:Differences between socket.io and websocketssocket.io 和 websockets 的区别
【发布时间】:2012-04-24 03:01:56
【问题描述】:

socket.io 和 websockets 有什么区别 node.js?
它们都是服务器推送技术吗? 我觉得唯一的不同是,

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

  2. 1234563

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

请澄清这一点。

【问题讨论】:

  • 关于为什么网络检查员没有抓到流量:见How to view WS/WSS Websocket request content using Firebug or other?
  • @treaz 你不需要 Firebug 或其他任何东西。 Chrome 的开发工具在网络选项卡下显示 WS 连接。
  • 也检查一下(不确定这是否是最新的)-educba.com/websocket-vs-socket-io
  • 我认为默认的 socket.io 行为(在服务器端)不是将 msg 发送给所有客户端。我错了吗?我认为 socket.emit(event, data) 会将数据发送到特定的客户端而不是全部
  • 请提供有关 Socket.io 与 RSocket 的任何文档?

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


【解决方案1】:

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

这是一本关于 WebSockets 和 Socket.IO 的好书。

http://davidwalsh.name/websocket

【讨论】:

  • Socket.IO 不是建立在 WebSockets 之上的,它只是在可用时使用这种技术。
  • 语义差异,我在其余答案中解释了这一点,但我已经更新了答案以反映这一点。
  • @moka,从你的话中我可以断定以下陈述是错误的吗? Socket.IO 实际上不仅仅是 WebSockets 之上的一层。
  • @PulakKantiBhattacharyya 您能否具体说明您指的是哪个声明? Socket.IO 不仅仅是 WebSockets 之上的一层,它具有不同的语义(用名称标记消息),并且可以对不同的协议进行故障转移,还有心跳机制。更多的是将 ID 附加到服务器端的客户端,等等。所以它不仅仅是一个包装器,它是一个功能齐全的库。事实上,近年来它并没有得到很好的支持,所以我建议使用 SockJS,它比 Socket.IO 更好、维护得更好。
  • @moka 一个月前我会同意你的。 Socket.io 1.0 现已发布,正在更新中。
【解决方案2】:

我将提供一个反对使用 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】:

    误解

    关于 WebSocket 和 Socket.IO 的常见误解很少:

    1. 第一个误解是使用 Socket.IO 比使用 WebSocket 容易得多,但事实并非如此。请参阅下面的示例。

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

    3. 第三个误解是 Socket.IO 将连接降级作为旧浏览器的后备。它实际上假定浏览器是旧的,并启动一个到服务器的 AJAX 连接,在交换了一些流量之后,它稍后会在支持 WebSocket 的浏览器上升级。详情见下文。

    我的实验

    我写了一个 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 服务器

    使用 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 客户端

    使用原生 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 客户端

    使用原生 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 秒

    来自这两个请求:

    1. HTML 页面本身
    2. 连接升级到 WebSocket

    (连接升级请求在开发者工具上可见,并带有 101 Switching Protocols 响应。)

    Socket.IO 结果

    6 个请求,181.56 KB,0.25 秒

    来自这 6 个请求:

    1. HTML 页面本身
    2. Socket.IO 的 JavaScript(180 KB)
    3. 第一个长轮询 AJAX 请求
    4. 第二个长轮询 AJAX 请求
    5. 第三次长轮询 AJAX 请求
    6. 连接升级到 WebSocket

    截图

    我在 localhost 上得到的 WebSocket 结果:

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

    测试自己

    快速开始:

    # 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 打开开发者工具,打开 Network 选项卡并使用 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 的浏览器兼容性:

    有关最新信息,请参阅 http://caniuse.com/websockets

    【讨论】:

    • 所以基本上你的意思是,websocket 比 socket.io 好?
    • @JackMoscovi 我不会说 WebSocket 一定更好。这一切都取决于要求。 WebSocket 的优点是它是一个 Web 标准(最初在 W3C 和 whatwg,现在在 IETF,5 年前有一个 RFC 发布),它非常轻量级,因为它是浏览器原生支持的,但浏览器支持虽然好不是通用的。 Socket.IO 支持更多的浏览器和更多的功能,但也带来了一些开销。有时一个更好,有时另一个。这就像在 querySelectorAll 和 jQuery 之间进行选择 - 答案并不总是相同的
    • 这里的答案很好!!在我看来,socket.io 在许多情况下不再是必需的......也请参阅这篇很棒的文章! medium.com/@ivanderbyl/…
    • @rsp 我不认为这些示例在功能上是等效的吗? Socket-io 处理中断时自动重新连接(发生在移动设备上)之类的事情,我认为为您处理的事情存在安全问题?您的普通 WS 示例虽然功能相同,但没有这些属性。
    • 很好的比较。然而,值得注意的是 Socket.io 增加了房间名称间距、大量连接细节、大量日志记录细节,并且有大量 Socket.IO 与 Angular、Vue、React 等的集成库。最重要的是,您可以禁用 Ajax 长轮询并直接通过 WebSocket 连接,就像原始 WebSocket 连接一样。这样一来,除了 180kb 库之外,您都可以平等地获得所有内容。除非您只需要最低限度,否则直接使用 WebSocket 会很痛苦。放置房间和访问社区 IP 对企业来说是一项艰巨的任务。
    【解决方案4】:

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

    【讨论】:

    • 据我所知,我认为这是一个有点糟糕的例子,因为 jQuery 不支持旧浏览器。这给新手的印象是现在应该使用 jQuery。如果您使用最新的 ECMA,则可以使用 babel。 :D 请原谅我的吹毛求疵,我只是看到新手一直无缘无故地使用 jQuery,因为他们在 javascript 之前学习 jquery,我只是想为减少这种不良实践现象做出贡献。
    • 很好地支持浏览器的不一致是 jQuery 的最初目的。如果您查看我的答案上的日期,您会明白的。当然,它老化得不好,因为现在不存在浏览器不一致了。
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      即使现代浏览器现在支持 WebSockets,我认为没有必要抛弃 SocketIO,它仍然在当今的任何项目中占有一席之地。这很容易理解,而且就个人而言,我通过 SocketIO 了解了 WebSockets 的工作原理。

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

      我要补充的关于 Socket.io 和 WebSockets 之间差异的另一点是,使用 Socket.io 进行集群并不是什么大问题。 Socket.io 提供Adapters,可用于将其与 Redis 链接以增强可扩展性。例如,您有 ioredissocket.io-redis

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

      【讨论】:

        【解决方案7】:

        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');
        

        【讨论】:

          【解决方案8】:

          tl;dr;

          比较它们就像比较餐厅食物(有时可能很贵,也许不是 100% 你想要的)和 自制食物,你必须收集和种植每种食物你自己的一种成分。

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


          这两种方法我都使用过。这是我的经验。

          SocketIO

          • 有自动连接

          • 有命名空间

          • 有房间

          • 有订阅服务

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

            (谈论订阅、取消订阅或向特定房间发送消息的协议,您必须在 websockets 中自己设计)

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

          • 已与redis等服务集成

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

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

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

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

          网络套接字

          • 你拥有绝对的控制权,这取决于你是谁,这可能非常好也可能非常糟糕
          • 它很轻巧(记住,它是一个协议,而不是一个库)
          • 您设计自己的架构和协议
          • 没有自动连接,如果需要,您可以自己实现
          • 没有订阅服务,你自己设计
          • 没有日志记录,你实现它
          • 没有后备支持
          • 没有房间或命名空间。如果你想要这样的概念,你自己实现它们
          • 不支持任何东西,你将是实现一切的人
          • 您首先必须专注于技术部分并设计进出您的 Websocket 的所有内容
          • 您必须先调试您的设计,这将花费您很长时间

          很明显,你可以看到我偏向于 SocketIO。我很想这么说,但我真的不是。

          我真的在与不使用 SocketIO 作斗争。我不想用它。我喜欢自己设计东西,自己解决问题。

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

          如果您是单人军队或尝试实现复杂功能的小团队,则为大型应用程序选择 Websocket 并不是一个简单的选择。我在 Websockets 中编写的代码比过去使用 SocketIO 编写的代码还要多,比使用 SocketIO 编写的代码简单十倍。

          我要说的是...... 如果您想要一个成品和设计,请选择 SocketIO。(除非您想要功能非常简单的东西)

          【讨论】:

            【解决方案9】:

            我想在 2021 年再提供一个答案。socket.io 自 2020 年 9 月以来再次得到积极维护。在 2019 年至 2020 年 8 月(近 2 年)期间,基本上没有任何活动,我原以为该项目可能是死了。

            Socket.io 还发了一篇文章叫Why Socket.IO in 2020?,除了回退到 HTTP 长轮询,我认为这两个特性是 socket.io 提供而 websocket 缺乏的

            • 自动重新连接
            • 一种将数据广播到一组给定客户端(房间/命名空间)的方法

            我发现 socket.io 的另一个方便的功能是用于 ws 服务器开发,尤其是我使用 docker 进行服务器部署。因为我总是启动超过 1 个服务器实例,所以跨 ws 服务器通信是必须的,socket.io 为它提供了https://socket.io/docs/v4/redis-adapter/

            使用 redis-adapter,将服务器进程扩展到多个节点很容易,而 ws 服务器的负载平衡很难。点击此处https://socket.io/docs/v4/using-multiple-nodes/ 了解更多信息。

            【讨论】:

              猜你喜欢
              • 2018-06-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-10-10
              • 1970-01-01
              • 2014-09-11
              • 2011-12-27
              相关资源
              最近更新 更多