Open anjia opened 5 years ago
它是一个 JavaScript framework。
支持实时、双向和基于事件的通信。它适用于每个平台、浏览器和设备,可靠性和速度也不错。
Socket.IO enables real-time, bidirectional and event-based communication.
Sockets(套接字)是大多数 real-time chat systems 用的解决方案,能在 client 和 server 之间提供双向通信通道。这样 server 就能给 clients 推送消息了。
通常的思路是:客户端发送了个消息,服务器取到它,再讲它推送到所有其他连接的 clients。
当然,也可以轮询服务器、跟踪 timestamps,但效率比较低
Socket.IO 由两部分组成:
socket.io
:一个和 Node.JS HTTP Server 集成的 serversocket.io-client
:一个在浏览器端加载的 client library
socket.io
会自动为 client 服务Socket.IO 背后的思想是你可以 send 和 receive 任何 events,数据也不限。 任何能 encode 成 JSON 的数据都可以,binary data 也可以。
目的:从 server 把事件 emit 到其它所有的 users
io.emit('some event', { for: 'everyone' });
socket.broadcast.emit
io.on('connection', function(socket){
socket.broadcast.emit('hi');
});
client 端的代码示例:
const socket = io();
// 1.会加载 socket.io-client, 且会连接
// defaults to trying to connect to the host that serves the page
const msgIpt = $('#m');
$('form').submit(function(){
socket.emit('chat message', msgIpt.val());
// 2.发送事件 'chat message'
msgIpt.val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});// 3.接收服务器转发/推送的消息
server 端的代码示例:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// 1.初始化一个新的 socket.io 实例, 参数是 HTTP server 对象
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
// 3.每个 socket 都有一个 'disconnect' 事件
// ...每次刷新页面,都是先 disconnect 再 connect
socket.on('chat message', function(msg){
console.log('message: ' + msg);
io.emit('chat message', msg); // 5.向所有人发送该消息
});// 4.自定义的事件 'chat message'
});
// 2.监听 'connection' 事件,当有进来的 sockets 时会触发
http.listen(3000, function(){
console.log('listening on *:3000');
});
Web Sockets 是 HTML5 诸多技术中的一个。
the WebSocket API ~ WebSockets
先来看下它和 Ajax 的区别。
Ajax | WebSocket |
---|---|
从 client 主动发出请求 | server 和 clients 之间双向消息推送 |
受 origin 限制 | 允许 cross-origin 通信 |
对 WebSockets 的理解,可以从以下几个方面:
ws
(安全)和wss
(不安全)onmessage
事件,消息体必须是字符串
ws
是一个升级了的http
请求 eg.在浏览器内聊天,就非常适合用 WebSocket
当浏览器不支持 WebSocket 时,可以使用一些回退传输:
Socket.IO 是对 WebSocket 的封装&扩展。可以无缝回退~
Socket.IO,一套 API,可以:
on()
,封装了每个 event type,类似 Node 那样
所以,Socket.IO 不仅仅是对 WebSocket 的封装,它是一个功能更全面的库
在网上查的资料:了解它两的不同,以便技术选型时参考
Socket.IO
https://stackoverflow.com/questions/10112178/differences-between-socket-io-and-websockets https://davidwalsh.name/websocket
https://codeburst.io/why-you-don-t-need-socket-io-6848f1c871cd
浏览器+服务器之间的异步通信 asynchronous communication between browsers and servers
作者指出: 虽然 Socket.IO 的兼容性特别地好,但它的成本比较高。诸如:
Socket.IO 实际是两个库
Socket programming 也介绍了套接字编程
另外,WebSockets 并不是真正的 sockets,虽然二者非常接近
可用选项:
{
'path': '/socket.io' // 要捕获的路径名称。默认是`/socket.io`
'serveClient': true, // 是否提供客户端文件
'adapter': '[Adapter]', // 要使用的适配器。默认是 Adapter 的实例,Adapter 是 socket.io 附带的,是基于内存的。请参阅socket.io-adapter
'origins': '*', // 允许的 origins
'parser': '-' // 要用的解析器。 默认是 Parser 的实例,Parse 也是 socket.io 附带的。详见 socket.io-parser
}
// 列出的,均为默认值
底层 Engine.IO 服务器的可用选项:
// 列出的,均为默认值
{
'pingTimeout': 5000, // ms, 多长时间之内,如果没有 pong 包,就会考虑关闭连接
'pingInterval': 25000, // ms, 多长时间发送一个新的 ping 包
'upgradeTimeout': 10000, // ms, 多长时间之内,取消未完成的传输升级(即会直接降级为 http 轮询或者其它非 websocket)
'maxHttpBufferSize': 10e7, // 在关闭会话之前,消息可以有多少字节或字符(规避 DoS)
'allowRequest': '', // 一个函数,第一个参数是接收到的给定的握手或升级请求,可以决定是否继续;第二个参数是一个函数,会传入已确定的信息,并调用 `fn(err, success)`,`success`是一个布尔值,false 意味着请求被拒绝,err 是一个错误码
'transports': ['polling', 'websocket'], // 允许连接的传输
'allowUpgrades': true, // 是否允许传输升级
'perMessageDeflate': true, // WebSocket permessage-deflate 扩展的参数(参见 ws module api 文档)。设置为 false 表示禁用
'httpCompression': true, // 控制轮询传输的 http 压缩(详见 zlib API 文档)。设置为 false 表示禁用
'cookie': 'io', // HTTP cookie 的名字,包含 client sid-会作为握手响应 headers 的一部分被发送。设置为 false 表示不发送
'cookiePath': '/', // cookie 选项的 path。如果是 false,不发送任何 path, 这意味着浏览器只会在 engine.io 上附加 cookie,path 是 `/engine.io`。设置为 false 表示不在所有的请求上保存 cookie
'cookieHttpOnly': true, // true 表示 cookie 是 HttpOnly 的,即不能被客户端的 API 访问到。如果上述两个选项 cookie 和 cookiePath 都是 false 的话,那这项不会起作用
'wsEngine': 'ws' // 使用的哪种 WebSocket server 实现。指定的模块,比如符合 ws 接口(详见 ws module API 文档)。默认是 ws。也可以安装 uws 模块来使用 c++ 插件
}
在以上选项中:
pingTimeout
和pingInterval
参数影响客户端知道服务器不再可用的延迟。比如,如果因为网络原因,而未正确关闭底层的 TCP 连接,客户端可能要等待 pingTimeout + pingInterval 毫秒,才能收到 disconnect
事件transports
数组的顺序很重要。默认情况下,首先建立长轮询连接,然后尽可能升级到 WebSocket。如果设置了['websocket']
则意味着当无法打开 WebSocket 连接时,不会出现回退。其它:
io.of('/connect')
// 直接用默认的/socket.io
也可以,前端同步改下就行
// 发送事件
socket.emit(eventName[, …args][, ack]) // 事件名字 eventName 是个字符串
// 接收事件 socket.on(eventName, callback)
https://socket.io/docs/server-api/
### client
```js
import io from 'socket.io-client'
// 创建一个 Socket Manager
const socket = io(url, { // url 默认是 window.location
path: '/socket.io', // String.
query: {}, // Object. 查询参数
parser: ; // 使用的解析器。默认是 socket.io 自带的 Parser。详见 socket.io-parser
reconnection: true, // Boolean. 是否自动重新连接。默认 true
reconnectionAttempts: 1, // Number. 尝试重新连接的次数。默认 Infinity
reconnectionDelay: 1000, // Number. 尝试重新连接之前的等待多长。默认 1000。但它受随机因子影响,比如默认的初始延时会介于 500-1500 ms
reconnectionDelayMax: 5000, // Number. 重新连接之间等待的最长时间。默认 5000。每次尝试都将重新连接延迟增加2倍以及随机化
randomizationFactor: 0.5, // Number. 默认 0.5。 0 <= randomizationFactor <= 1
timeout: 20000, // Number. 连接超时, 默认 20000。 如果多长时间之内连接还没建成功,则认为失败,会触发 connect_error 和 connect_timeout 事件。进而触发重连机制
autoConnect: true, // Boolean. 默认是 true。如果设置成 false,则必须手动调用 manager.open,在你觉得合适的时候
transports: ['websocket', 'polling'] // Array. 要尝试的传输列表(按序)。默认是 ['polling', 'websocket']。
upgrade: true, // Boolean.
forceJSONP: true, // Boolean. 轮询传输时强制 JSONP
jsonp: true, // Boolean. 轮询时...
// ....
})
/**
* options 对象可接收的参数:
* - io.Manager: https://github.com/socketio/socket.io-client/blob/master/docs/API.md#new-managerurl-options
* - engine.io-client: https://github.com/socketio/engine.io-client#methods
*/
https://github.com/socketio/socket.io-client/blob/master/docs/API.md
移动端,当浏览器最小化之后
send
/ 任何的 HTTP 请求,均会被暂存,不执行
异同点 | Socket.IO | Centrifugo |
---|---|---|
设置 ping-pong | 在 Server 端 | 在 Client 端 |
浏览器不可见时 | 依然有 ping-pong | 没 ping-pong 了 |
.disconnect() |
连接断了,但是 event_name 还在;所以再次.connect() 时不用再监听事件 |
连接断了,也会取消订阅;所以再次.connect() 时需要重新订阅 channel |
server 判断 client 是否在线 | 客户端.close() /.disconnect() |
客户端.unsubscribe() 即可 |
断网重连后 | ws 会自动连接,功能恢复 | ws 会自动连接&自动订阅,功能恢复 |
功能:
场景:
兼容只测了功能,未发现异常 但未深入到库的底部协议/连接机制
WebSockets
Web Sockets 是 HTML5 诸多技术中的一个。
the WebSocket API ~ WebSockets
先来看下它和 Ajax 的区别。
Ajax WebSocket 从 client 主动发出请求 server 和 clients 之间双向消息推送 受 origin 限制 允许 cross-origin 通信 对 WebSockets 的理解,可以从以下几个方面:
- 协议可以使用
ws
(安全)和wss
(不安全)- 它是在单个 TCP socket(套接字)上进行通信的
onmessage
事件,消息体必须是字符串
ws
是一个升级了的http
请求 eg.在浏览器内聊天,就非常适合用 WebSocket当浏览器不支持 WebSocket 时,可以使用一些回退传输:
- Flash。但它的缺点是,有些客户端是没有装/不能装 Flash
Ajax 长轮询
- 有效,但并未针对消息发送做优化
- 所以,并不是最佳方法
ws安全还是wss是安全的
Vue-Socket.io 是一个 Vuejs 的 socket.io 集成。
https://github.com/MetinSeylan/Vue-Socket.io