误解
关于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.
我的实验
我写了一个npm模块来演示WebSocket和Socket的区别。IO:
https://www.npmjs.com/package/websocket-vs-socket.io
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');
来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
套接字。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');
来源: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
套接字。输入输出端
套接字。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); });
来源:https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
网络流量
要查看网络流量的差异,您可以运行我的测试。以下是我得到的结果:
WebSocket结果
2个请求,1.50 KB, 0.05 s
从这两个请求中:
HTML页面本身
连接升级到WebSocket
(连接升级请求在开发人员工具上可见,并带有101交换协议响应。)
套接字。输入输出结果
6个请求,181.56 KB, 0.25 s
从这6个要求中:
HTML页面本身
套接字。IO的JavaScript(180千字节)
第一个长轮询AJAX请求
第二个长轮询AJAX请求
第三个长轮询AJAX请求
连接升级到WebSocket
截图
我在localhost上得到的WebSocket结果:
套接字。我在localhost上得到的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在Can I Use上的浏览器兼容性:
查看http://caniuse.com/websockets获取最新信息。