You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
real-time-communication/实时通信方案.md

5.7 KiB

实时通信方案

网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket (baidu.com)

Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE (taodudu.cc)

详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket (360doc.com)

建设介绍

  1. 采用工具

后端:ws ^8.13.0

前端:socket.io ^4.7.2

  1. demo操作
# 启动server
npm i
npm run start:server

# 启动客户端
cd client
npm i
npm run start:client

# 进入页面输入昵称和ServerIP即可开始聊天

WebSocket

WebSocket是客户端和服务器之间的可以双向通信的全双工通信协议。

  1. 特点

(1)建立在 TCP 协议之上,服务器端的实现比较容易。(建立通信时采用http协议)

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据(blob对象或Arraybuffer对象)

(5)收到的数据类型 可以使用binaryType 指定, 显式指定收到的二进制数据类型

(6)没有同源限制,客户端可以与任意服务器通信。

(7)协议标识符是ws(握手http)(如果加密,则为wss(tcp +TLS)),服务器网址就是 URL。

  1. 使用
const socket = new WebSocket(`ws://hostname:port/path`);
socket.onopen = event => {
    // 当socket与服务器练级成功时触发
}
socket.onerror = event =>{
    // 当socket出现错误时触发,包括网络错误,断开连接,服务器错误等
    console.error('Error',event)
}
socket.onclose = event => {
    // 当socket断开连接时触发
    // WebSocket没有断线重连机制,如需重连,在此方法内编写重连逻辑
}
ws.onmessage = event => {
    const msg = event.data
    // 当接收到服务器发送的消息时触发
    ws.send('消息内容');// 这里可以选择二进制数据发送
}

SSE

SSE的本质其实就是一个HTTP的长连接,只不过它给客户端发送的不是一次性的数据包,而是一个stream流,格式为text/event-stream。所以客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。

  1. 特点

1)SSE 使用 HTTP 协议,现有的服务器软件都支持。WebSocket 是一个独立协议。

2)SSE 属于轻量级,使用简单;WebSocket 协议相对复杂。

3)SSE 默认支持断线重连,WebSocket 需要自己实现。

4)SSE 一般只用来传送文本,二进制数据需要编码后传送,WebSocket 默认支持传送二进制数据。

5)SSE 支持自定义发送的消息类型。

  1. 缺点

1)客户端无法发送消息,需要通过接口单独请求

  1. 使用
const eventSource = new EventSource('/api/system/msg/connect?id=' + userId, {
    headers: {
        'Content-Type': 'text/event-stream',
        'Authorization': 'token'
    }
});
eventSource.addEventListener("open", function (e) {
    console.log('open successfully')
})
/*
* message:后端返回信息,格式可以和后端协商
*/
eventSource.addEventListener("message", function (e) {
    console.log(e.data)
})
/*
* error:错误
*/
eventSource.addEventListener("error", function (err) {
    // console.log(err)
    // 类似的返回信息验证,这里是实例
    err && err.status === 401 && console.log('not authorized')
})

长链接

客户端和服务端建立连接后不进行断开,之后客户端再次访问这个服务器上的内容时,继续使用这一条连接通道。

短链接

客户端和服务端建立连接,发送完数据后立马断开连接。下次要取数据,需要再次建立连接。

Http长连接和TCP长连接的区别在于: TCP 的长连接需要自己去维护一套心跳策略。而Http只需要在请求头加入keep-alive:true即可实现长连接。

Socket.IO

Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟, 双向和基于事件的通信。

  1. 特点

1)它建立在 WebSocket 协议之上,并提供额外的保证,如果无法建立WebSocket连接,连接将回退到HTTP长轮询或自动重新连接。

2)自动重新连接

3)数据包缓冲。当客户端断开连接时,数据包会自动缓冲,并在重新连接时发送。

import { io } from "https://cdn.socket.io/4.3.2/socket.io.esm.min.js";
const socket = io("http://127.0.0.1:3000")

socket.on("connect", () => {
    //监听连接是否成功
    console.log("链接成功");
});
socket.on("disconnect", (reason) => {
    //监听连接异常中断
    console.log("中断", reason);
});

socket.on("message_event", (data) => {
    // "message_event"时后端定义的发送字段
    console.log("接收到的消息", data);
})

// 前端主动断开链接
socket.close()
socket.disconnect()

socket.on('connect',() => {
    // 与服务器连接成功
    console.log('socket链接成功!'+socket.id)
})
// 其他事件
// connect:连接成功
// connecting:正在连接
// disconnect:断开连接
// connect_failed:连接失败
// error:错误发生,并且无法被其他事件类型所处理
// reconnect_failed:重连失败
// reconnect:成功重连
// reconnecting:正在重连