插座之间的差异。IO和websockets

socket之间有什么区别。IO和websockets在 node . js ?< br > 它们都是服务器推送技术吗? 我觉得唯一的区别是

  1. 套接字。IO允许我通过指定事件名称来发送/发出消息。

  2. 对于socket。io消息从服务器将到达所有客户端,但同样在websockets,我被迫保持一个数组的所有连接和循环通过它发送消息到所有客户端。

< p >, 我想知道为什么网络检查员(如Chrome/firebug/fiddler)无法从服务器捕捉这些消息(从socket.io/websocket) ?< / p >

请澄清这一点。

297688 次浏览

它的优点是简化了您在#2中所描述的WebSockets的使用,更重要的是,当浏览器或服务器不支持WebSockets时,它提供了对其他协议的故障转移。我会避免直接使用WebSockets,除非你非常熟悉它们不能工作的环境,并且你有能力绕过这些限制。

这是一个关于WebSockets和Socket.IO的很好的阅读。

http://davidwalsh.name/websocket

我将提供一个反对使用socket.io的参数。

我认为是使用socket。仅仅因为IO有后援就不是个好主意。让IE8 RIP。

在过去有很多情况下,新版本的NodeJS破坏了socket.io。你可以在这些列表中找到例子。# EYZ0

如果你要开发一个Android应用或者其他需要与现有应用配合的东西,你可能会马上使用WS, socket。IO可能会给你带来一些麻烦…

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

误解

关于WebSocket和Socket有一些常见的误解。IO:

  1. 第一个误解是使用Socket。IO明显比使用WebSocket简单,但事实并非如此。请看下面的例子。

  2. 第二个误解是浏览器并不广泛支持WebSocket。更多信息见下文。

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

我的实验

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

  • https://www.npmjs.com/package/websocket-vs-socket.io < a href = " https://www.npmjs.com/package/websocket-vs-socket.io " > < / >
  • https://github.com/rsp/node-websocket-vs-socket.io < a href = " https://github.com/rsp/node-websocket-vs-socket.io " > < / >

这是一个服务器端和客户端代码的简单示例——客户端使用WebSocket或Socket连接到服务器。IO和服务器以1秒为间隔发送三条消息,这些消息由客户端添加到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');

来源:# EYZ0

套接字。IO服务器

套接字。使用Express.js的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');

来源:# EYZ0

客户端

比较使用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); });

来源:# EYZ0

套接字。输入输出端

套接字。IO客户端示例使用香草JavaScript:

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

来源:# EYZ0

网络流量

要查看网络流量的差异,可以使用运行我的测试。以下是我得到的结果:

WebSocket结果

2个请求,1.50 KB, 0.05 s

从这两个请求中:

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

(连接升级请求在开发人员工具上可见,并带有101交换协议响应。)

套接字。输入输出结果

6个请求,181.56 KB, 0.25 s

从这6个要求中:

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

截图

我在localhost上得到的WebSocket结果:

WebSocket results - WebSocket -vs-socket. < / >

套接字。我在localhost上得到的IO结果:

套接字。IO结果- websocket-vs-socket。io模块 < / >

测试自己

快速启动:

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

在浏览器中打开http://localhost:3001/,用Shift+Ctrl+I打开开发工具,打开Network选项卡,用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月我可以用上WebSocket的浏览器兼容性:

enter image description here

请参阅http://caniuse.com/websockets获取最新信息。

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

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

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

正如在本主题中提到的,有很多Angular、React等的集成库,以及TypeScript和其他编程语言的定义类型。

我要补充的另一点是Socket之间的区别。io和WebSockets是与Socket的集群。IO不是什么大问题。套接字。io提供了适配器,可用于与Redis链接,以增强可伸缩性。例如,你有ioredissocket.io-redis

是的,我知道,SocketCluster是存在的,但这是跑题了。

https://socket.io/docs/#What-Socket-IO-is-not(和我的强调)

套接字。IO不是

套接字。IO是一个WebSocket实现。尽管插座。IO确实在可能的情况下使用WebSocket作为传输,它为每个数据包添加了一些元数据:当需要消息确认时,数据包类型、命名空间和数据包id。这就是为什么是WebSocket客户端将能够成功连接到Socket。IO服务器套接字。IO客户端将能够连接到WebSocket服务器。请参阅协议规范在这里

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

tl,博士;

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

也许如果你只想吃苹果,后者更好。但如果你想要一些复杂的东西,而你又孤身一人,那真的不值得你自己烹饪和制作所有的食材。


这两种我都用过。以下是我的经验。

SocketIO

  • < p >符

  • < p >名称空间

  • < p >有房间

  • 有订阅服务

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

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

  • 具有良好的日志支持

  • 与redis等服务集成

  • 在WS不支持的情况下有回退(好吧,这是越来越罕见的情况)

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

  • 整个体系结构是由不是你的人支持和设计的,因此你不必花时间设计和实现上面的任何东西,但是你可以直接编写业务规则。

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

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

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

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

但如果你想要经营一家企业,而不仅仅是千线工程,你要去选择Websockets,你就必须去自己完成每一件事。你必须调试一切。你必须建立自己的订阅服务。你自己的协议。你拥有一切。你必须确保一切都很复杂。在这条路上你会犯很多错误。您将花费大量时间设计和调试所有内容。我以前是,现在也是。我正在使用websockets和我来这里的原因是,对于一个试图为他的初创公司解决业务规则而不是处理Websocket设计术语的人来说,他们是无法忍受的。

如果你是一个人的团队或者一个小团队想要实现复杂的功能,那么为一个大的应用程序选择Websockets并不是一个简单的选择。我用Websockets写的代码比以前用SocketIO写的要多,而且比用SocketIO简单十倍。

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

我想在2021年再提供一个答案。套接字。在2019年9月至2020年8月(将近2年)期间,基本上没有任何活动,我本以为该项目可能已经死亡。

套接字。io也发表了一篇文章,叫套接字的原因。2020年的IO ?,除了退回到HTTP长轮询,我认为这2个特性socket是什么。IO提供,websocket缺乏

  • 端的自动重连接
  • 将数据广播到给定客户端集(房间/名称空间)的方法

我发现socket的另一个特性。io方便是为ws服务器开发,特别是我使用docker部署我的服务器。因为我总是启动一个以上的服务器实例,跨ws服务器通信是必须的和套接字。io为它提供https://socket.io/docs/v4/redis-adapter/

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

TLDR:

的套接字。io'是一个应用程序层 规范,可以在/使用应用程序层 规范 'websockets'的顶部实现。

< p > # EYZ0
# EYZ0 < / p >

我认为简单的答案是在基本的web技术定义中:

  1. 规范:一种文件化的标准,详细说明一个程序要达到的要求,以便被标记为“某些sepc的实现”。在构建程序时,实现这个橡皮图章是很重要的,因为任何程序都只能在机器执行代码时发挥作用。编程基本上是建立在规范之上的,如果不遵守规范,代码将无法正确执行。然而,# EYZ0。它只是一个文本文档。
  2. 实现:这是实际的、可执行的代码,它完成了规范要求做的事情。
  3. 应用层——定义通过传输发送的消息和握手的系统。这是你在使用HTTP/Websockets/Socketio时必须知道的东西。它定义了如何建立连接、验证、发送数据以及如何到达。