node.js socket.io 和 websockets 之间的差异
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10112178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Differences between socket.io and websockets
提问by Vivek Mohan
What are the differences between socket.io and websockets in
node.js?
Are they both server push technologies?
The only differences I felt was,
node.js 中的 socket.io 和 websockets 有什么区别?
它们都是服务器推送技术吗?我觉得唯一的不同是,
socket.io allowed me to send/emit messages by specifying an event name.
In the case of socket.io a message from server will reach on all clients, but for the same in websockets I was forced to keep an array of all connections and loop through it to send messages to all clients.
socket.io 允许我通过指定事件名称来发送/发出消息。
在 socket.io 的情况下,来自服务器的消息将到达所有客户端,但在 websockets 中,我被迫保留所有连接的数组并循环通过它向所有客户端发送消息。
Also, I wonder why web inspectors (like Chrome/firebug/fiddler) are unable to catch these messages (from socket.io/websocket) from server?
另外,我想知道为什么网络检查员(如 Chrome/firebug/fiddler)无法从服务器捕获这些消息(来自 socket.io/websocket)?
Please clarify this.
请澄清这一点。
采纳答案by Timothy Strimple
Its advantages are that it simplifies the usage of WebSockets as you described in #2, and probably more importantly it provides fail-overs to other protocols in the event that WebSockets are not supported on the browser or server. I would avoid using WebSockets directly unless you are very familiar with what environments they don't work and you are capable of working around those limitations.
它的优点是它简化了您在 #2 中描述的 WebSockets 的使用,而且可能更重要的是,如果浏览器或服务器不支持 WebSockets,它可以提供到其他协议的故障转移。我会避免直接使用 WebSockets,除非您非常熟悉它们不工作的环境并且您能够解决这些限制。
This is a good read on both WebSockets and Socket.IO.
这是关于 WebSockets 和 Socket.IO 的好读物。
回答by rsp
Misconceptions
误解
There are few common misconceptions regarding WebSocket and Socket.IO:
关于 WebSocket 和 Socket.IO 有几个常见的误解:
The first misconception is that using Socket.IO is significantly easier than using WebSocket which doesn't seem to be the case. See examples below.
The second misconception is that WebSocket is not widely supported in the browsers. See below for more info.
The third misconception is that Socket.IO downgrades the connection as a fallback on older browsers. It actually assumes that the browser is old and starts an AJAX connection to the server, that gets later upgraded on browsers supporting WebSocket, after some traffic is exchanged. See below for details.
第一个误解是使用 Socket.IO 比使用 WebSocket 容易得多,但事实并非如此。请参阅下面的示例。
第二个误解是 WebSocket 并未在浏览器中得到广泛支持。请参阅下文了解更多信息。
第三个误解是 Socket.IO 将连接降级作为旧浏览器的后备。它实际上假设浏览器是旧的,并启动到服务器的 AJAX 连接,在交换一些流量后,稍后在支持 WebSocket 的浏览器上升级。详情请见下文。
My experiment
我的实验
I wrote an npm module to demonstrate the difference between WebSocket and Socket.IO:
我写了一个 npm 模块来演示 WebSocket 和 Socket.IO 之间的区别:
- https://www.npmjs.com/package/websocket-vs-socket.io
- https://github.com/rsp/node-websocket-vs-socket.io
- https://www.npmjs.com/package/websocket-vs-socket.io
- https://github.com/rsp/node-websocket-vs-socket.io
It is a simple example of server-side and client-side code - the client connects to the server using either WebSocket or Socket.IO and the server sends three messages in 1s intervals, which are added to the DOM by the client.
这是服务器端和客户端代码的一个简单示例——客户端使用 WebSocket 或 Socket.IO 连接到服务器,服务器以 1 秒的间隔发送三个消息,这些消息由客户端添加到 DOM。
Server-side
服务器端
Compare the server-side example of using WebSocket and Socket.IO to do the same in an Express.js app:
比较使用 WebSocket 和 Socket.IO 在 Express.js 应用程序中执行相同操作的服务器端示例:
WebSocket Server
网络套接字服务器
WebSocket server example using 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');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
来源:https: //github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
Socket.IO Server
Socket.IO 服务器
Socket.IO server example using Express.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');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
来源:https: //github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
Client-side
客户端
Compare the client-side example of using WebSocket and Socket.IO to do the same in the browser:
比较使用 WebSocket 和 Socket.IO 在浏览器中执行相同操作的客户端示例:
WebSocket Client
网络套接字客户端
WebSocket client example using vanilla JavaScript:
使用 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); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html
来源:https: //github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html
Socket.IO Client
Socket.IO客户端
Socket.IO client example using vanilla JavaScript:
使用原生 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); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
来源:https: //github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
Network traffic
网络流量
To see the difference in network traffic you can run my test. Here are the results that I got:
要查看网络流量的差异,您可以运行我的测试。以下是我得到的结果:
WebSocket Results
WebSocket 结果
2 requests, 1.50 KB, 0.05 s
2 个请求,1.50 KB,0.05 秒
From those 2 requests:
从这两个请求中:
- HTML page itself
- connection upgrade to WebSocket
- HTML 页面本身
- 连接升级到 WebSocket
(The connection upgrade request is visible on the developer tools with a 101 Switching Protocols response.)
(连接升级请求在具有 101 Switching Protocols 响应的开发人员工具上可见。)
Socket.IO Results
Socket.IO 结果
6 requests, 181.56 KB, 0.25 s
6 个请求,181.56 KB,0.25 秒
From those 6 requests:
从这 6 个请求中:
- the HTML page itself
- Socket.IO's JavaScript (180 kilobytes)
- first long polling AJAX request
- second long polling AJAX request
- third long polling AJAX request
- connection upgrade to WebSocket
- HTML 页面本身
- Socket.IO 的 JavaScript(180 KB)
- 第一个长轮询 AJAX 请求
- 第二个长轮询 AJAX 请求
- 第三个长轮询 AJAX 请求
- 连接升级到 WebSocket
Screenshots
截图
WebSocket results that I got on localhost:
我在本地主机上得到的 WebSocket 结果:
Socket.IO results that I got on localhost:
我在本地主机上得到的 Socket.IO 结果:
Test yourself
测试自己
Quick start:
快速开始:
# Install:
npm i -g websocket-vs-socket.io
# Run the server:
websocket-vs-socket.io
Open http://localhost:3001/in your browser, open developer tools with Shift+Ctrl+I, open the Network tab and reload the page with Ctrl+R to see the network traffic for the WebSocket version.
在浏览器中打开http://localhost:3001/,使用 Shift+Ctrl+I 打开开发人员工具,打开网络选项卡并使用 Ctrl+R 重新加载页面以查看 WebSocket 版本的网络流量。
Open http://localhost:3002/in your browser, open developer tools with Shift+Ctrl+I, open the Network tab and reload the page with Ctrl+R to see the network traffic for the Socket.IO version.
在浏览器中打开http://localhost:3002/,使用 Shift+Ctrl+I 打开开发者工具,打开网络选项卡并使用 Ctrl+R 重新加载页面以查看 Socket.IO 版本的网络流量。
To uninstall:
卸载:
# Uninstall:
npm rm -g websocket-vs-socket.io
Browser compatibility
浏览器兼容性
As of June 2016 WebSocket works on everything except Opera Mini, including IE higher than 9.
截至 2016 年 6 月,WebSocket 适用于除 Opera Mini 之外的所有内容,包括 IE 高于 9。
This is the browser compatibility of WebSocket on Can I Useas of June 2016:
这是截至 2016 年 6 月WebSocket 在Can I Use上的浏览器兼容性:
See http://caniuse.com/websocketsfor up-to-date info.
有关最新信息,请参阅http://caniuse.com/websockets。
回答by Victorio Berra
Im going to provide an argument against using socket.io.
我将提供一个反对使用 socket.io 的论据。
I think using socket.io solely because it has fallbacks isnt a good idea. Let IE8 RIP.
我认为使用 socket.io 仅仅因为它具有回退功能并不是一个好主意。让IE8 RIP。
In the past there have been many cases where new versions of NodeJS has broken socket.io. You can check these lists for examples... https://github.com/socketio/socket.io/issues?q=install+error
过去有很多案例是新版本的 NodeJS 破坏了 socket.io。您可以查看这些列表以获取示例... https://github.com/socketio/socket.io/issues?q=install+error
If you go to develop an Android app or something that needs to work with your existing app, you would probably be okay working with WS right away, socket.io might give you some trouble there...
如果您要开发 Android 应用程序或需要与现有应用程序配合使用的应用程序,您可能马上就可以使用 WS 了,socket.io 可能会给您带来一些麻烦...
Plus the WS module for Node.JS is amazingly simple to use.
此外,Node.JS 的 WS 模块使用起来非常简单。
回答by Dev Agrawal
Using Socket.IO is basically like using jQuery - you want to support older browsers, you need to write less code and the library will provide with fallbacks. Socket.io uses the websockets technology if available, and if not, checks the best communication type available and uses it.
使用 Socket.IO 基本上就像使用 jQuery - 你想支持旧浏览器,你需要编写更少的代码,库将提供回退。Socket.io 使用 websockets 技术(如果可用),如果没有,则检查可用的最佳通信类型并使用它。
回答by Maxime Lafarie
Even if modern browsers support WebSockets now, I think there is no need to throw SocketIO away and it still has its place in any nowadays project. It's easy to understand, and personally, I learned how WebSockets work thanks to SocketIO.
即使现代浏览器现在支持 WebSockets,我认为也没有必要抛弃 SocketIO,它在当今任何项目中仍然占有一席之地。它很容易理解,而且我个人通过 SocketIO 了解了 WebSockets 的工作原理。
As said in this topic, there's a plenty of integration libraries for Angular, React, etc. and definition types for TypeScript and other programming languages.
如本主题所述,Angular、React 等有大量集成库,TypeScript 和其他编程语言有很多定义类型。
The other point I would add to the differences between Socket.io and WebSockets is that clustering with Socket.io is not a big deal. Socket.io offers Adaptersthat can be used to link it with Redis to enhance scalability. You have ioredisand socket.io-redisfor example.
对于 Socket.io 和 WebSockets 之间的差异,我要补充的另一点是,使用 Socket.io 进行集群并不是什么大问题。Socket.io 提供了可用于将其与 Redis 链接以增强可扩展性的适配器。例如,您有ioredis和socket.io-redis。
Yes I know, SocketClusterexists, but that's off-topic.
是的,我知道,SocketCluster存在,但那是题外话。
回答by Nitin .
Socket.IO uses WebSocket and when WebSocket is not available uses fallback algo to make real time connections.
Socket.IO 使用 WebSocket,当 WebSocket 不可用时,使用回退算法进行实时连接。
回答by Ken Lin
https://socket.io/docs/#What-Socket-IO-is-not(with my emphasis)
https://socket.io/docs/#What-Socket-IO-is-not(重点是)
What Socket.IO is not
Socket.IO is NOTa WebSocket implementation. Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the packet id when a message acknowledgement is needed. That is why a WebSocket client will notbe able to successfully connect to a Socket.IO server, and a Socket.IO client will notbe able to connect to a WebSocket servereither. Please see the protocol specification here.
// WARNING: the client will NOT be able to connect! const client = io('ws://echo.websocket.org');
Socket.IO 不是什么
Socket.IO不是WebSocket 实现。尽管 Socket.IO 确实在可能的情况下使用 WebSocket 作为传输,但它为每个数据包添加了一些元数据:数据包类型、命名空间和需要消息确认时的数据包 ID。这就是为什么WebSocket 客户端将无法成功连接到 Socket.IO 服务器,而Socket.IO 客户端也无法连接到 WebSocket 服务器的原因。请在此处查看协议规范。
// WARNING: the client will NOT be able to connect! const client = io('ws://echo.websocket.org');


