socket.io和websockets之间有什么区别
Node.js的?
它们都是服务器推送技术吗?
我感觉到的唯一区别是,
socket.io允许我通过指定事件名称来发送/发送消息。
在socket.io的情况下,来自服务器的消息将到达所有客户端,但对于websockets中的相同内容,我被迫保留所有连接的数组并循环通过它以向所有客户端发送消息。
另外, 我想知道为什么网络检查员(如Chrome / firebug / fiddler)无法从服务器捕获这些消息(来自socket.io/websocket)?
请澄清一下。
答案 0 :(得分:409)
关于WebSocket和Socket.IO,几乎没有什么常见的误解:
第一个误解是使用Socket.IO比使用WebSocket要容易得多,而WebSocket似乎并非如此。见下面的例子。
第二个误解是WebSocket在浏览器中没有得到广泛支持。有关详细信息,请参阅下文。
第三个误解是Socket.IO将连接降级为旧浏览器的后备。它实际上假设浏览器是旧的并且启动与服务器的AJAX连接,稍后在交换一些流量之后在支持WebSocket的浏览器上升级。有关详细信息,请参阅下文。
我写了一个npm模块来演示WebSocket和Socket.IO之间的区别:
这是服务器端和客户端代码的简单示例 - 客户端使用WebSocket或Socket.IO连接到服务器,服务器以1s间隔发送三条消息,由客户端添加到DOM
比较使用WebSocket和Socket.IO的服务器端示例在Express.js应用程序中执行相同的操作:
使用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
使用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在浏览器中执行相同操作的客户端示例:
使用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
使用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。以下是我得到的结果:
从这2个请求中:
(连接升级请求在具有101切换协议响应的开发人员工具上可见。)
根据这6项要求:
我在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打开开发人员工具,打开网络选项卡,然后使用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了解最新信息。
答案 1 :(得分:291)
它的优点在于它简化了#2中描述的WebSockets的使用,并且可能更重要的是,它在浏览器或服务器不支持WebSockets的情况下为其他协议提供故障转移。我会避免直接使用WebSockets,除非您非常熟悉它们不起作用的环境,并且您能够解决这些限制。
这是对WebSockets和Socket.IO的好读。
答案 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
很显然,您可以看到我对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链接以增强可伸缩性。例如,您有ioredis和socket.io-redis。
是的,我知道SocketCluster存在,但这是题外话。