better-ws库使用文档
介绍
本项目为基于websocket的二次封装,自定义协议,需与配套的后端一同使用。本工具增加了消息确认机制,通过msg_id与配对的ack进行消息收发的确认,若未收到则一定时间后进行重发。better-ws
借鉴了axios的拦截器,实现了一系列自己的拦截器,在websocket的通信的生命周期中的恰当位置执行这些拦截器钩子。除此之外还增加了类似http请求的通信方式rpc消息,通过promise封装,发送消息后再.then
中等待消息结果,或.catch
中处理发送失败事件。当前版本支持web端与小程序端,使用传参略有差异,但基本方法一致
安装
yarn add better-ws
or npm install better-ws
引入better-ws
import BetterWS from 'better-ws';
使用方法
创建对象
web端
const bws = new BetterWS({
url: 'ws://localhost:8400/api',
protocols: ['12345678'],
maxReConnectCount: 5
})
小程序端
const bws = new BetterWS({
url: 'ws://localhost:8400/api',
protocols: ['12345678'],
maxReConnectCount: 5
}, wx);
注意事项 由于小程序端无法直接使用websocket,必须借助
wx
提供的api,因此小程序端需要传入第二个参数wx
。
BetterWS配置对象
修改全局默认配置
类似axios
,better-ws
也可以修改全局默认配置项,通过BetterWS.defauls.xxx
进行修改。
配置对象数据结构及默认值
配置项参数config
数据结构为
interface BetterWSConfig {
url?: string; // 服务器地址
protocols?: string | Array<string>; // 子协议
reconnect?: boolean; // 是否重连 true
maxReConnectCount?: number; // 最大重连次数 5
reconnectInterval?: number; // 重连间隔 5000 (ms)
heartbeatInterval?: number; // 心跳ping发送间隔 10000 (ms)
disabledDefaultHeartBeat?: boolean; // 是否禁用默认心跳发送函数
reSendInterval?: number; // 消息重发间隔 5000
timeout?: number; // 超时时间设置 10000
cancel_rec?: boolean; // 取消重连 false
heartbeatResponseResult?: string; // 接收到的心跳字符串 pong
}
初始化配置定义 除了修改全局默认配置,还可像上方创建对象时将配置对象作为第一个参数传递进去。初始化配置项会与默认配置进行合并。
连接websocket
以上通过new创建的对象仅仅是个BetterWS类的实例,需要通过connect
方法进行与服务器的连接。
bws.connect()
返回一个Promise实例,如果连接成功可以直接在then方法中处理后续结果,如果一直连接失败,会在最大连接失败次数后进入抛出异常,可在catch方法中进行捕获。
const bws = new BetterWS({
url: 'ws://localhost:8400/api',
protocols: ['12345678'],
maxReConnectCount: Infinity
})
bws.connect().then((res) => {
// res: 连接成功的结构,小程序与web端不同
}).catch(err => {
// 重连次数结束后还是失败的情况进入失败处理
})
处理器processors
处理器的使用
better-ws
的处理器参考了axios
拦截器的实现方式,使用方法也与之大同小异。
处理器的作用就是在websocket运行的各种生命周期中插入一些钩子函数,不同的处理器相当于不同的钩子,可以在上面绑定多个函数。
例如普通消息函数处理器,使用方法如下
const bws = new BetterWS({
url: 'ws://localhost:8400/api',
protocols: ['12345678'],
maxReConnectCount: Infinity
})
bws.processors.message.use(messageProcess1)
bws.processors.message.use(messageProcess2)
bws.processors.message.use(messageProcess3)
function messageProcess1() {
...
}
function messageProcess2() {
...
}
function messageProcess3() {
...
}
处理器可以像axios
取消拦截器一样取消处理器
bws.processors.message.use(messageProcess1)
bws.processors.message.use(messageProcess2)
bws.processors.message.use(messageProcess3)
function messageProcess1() {
console.log('1')
}
const pid = function messageProcess2() {
console.log('2')
}
bws.processors.message.eject(pid); // 取消第二个消息处理事件, 如果接收到消息,则会执行第一个与第三个处理函数,打印出1,3
function messageProcess3() {
console.log('3')
}
处理器的种类
处理器类型共有如下几种:
-
heartbeat
: 心跳发送函数的处理器 -
heartbeatResponse
: 心跳返回结果函数的处理器 -
open
: websocket连接成功后的函数处理器 -
openError
: websocket打开失败的函数处理器,小程序端只有error处理器包含openError的报错处理 -
error
: 错误处理器 -
message
: 普通消息的函数处理器 -
error_message
: 错误消息的函数处理器 -
seq_message
: 队列消息的函数处理器 -
rpc_message
: rpc消息的函数处理器, 仅处理服务端发送的rpc请求 -
close
: websocket关闭的函数处理器 -
wxCloseSuccess
: 微信关闭连接成功回调 -
wxCloseFail
: 微信关闭连接失败回调 -
wxCloseComplete
: 微信关闭连接成功失败都调用的回调
tips: 微信关闭WebSocket后会先触发微信关闭的回调,然后才会触发onClose。 例如在关闭连接后,此时还没有触发onClose,但触发了微信关闭的回调,在此期间,如果还调用了websocket的发送方法,就会报错,因此,像心跳函数,其中定义的定时器timer会在微信关闭连接成功的回调中进行自动清除。如有其它类似需求,请在正确的处理器中添加相关处理函数。
消息的发送
better-ws
通过send
方法进行事件消息的发送,默认事件为'hi',由于协议规定,每个消息的发送都会带有事件,以此确定消息的种类,便于拦截处理。send
方法为最普通的消息发送方法。
bws.send(msg: any, event?: string, seqId?: string)
:
-
mgs
: 消息内容, -
event
: 事件类型 -
seqId
: 队列id
bws内部对不同的seq分别维护了不同的消息队列,断连后如果及时重连会自动发送未发送的消息。默认seqId不用填写,会自动进入普通消息的消息队列。 消息发送失败后会在设置的重发间隔后自动进行重发,达到最大重发次数后仍失败会报错。
RPC类型消息
rpc消息与HTTP请求类似,发送一个请求后,会等待这个请求的结果,如果在默认间隔内没有收到回复,则会继续发送,直到收到回复.
direct方法可以发送一个rpc请求,并返回一个Promise实例,在.then
方法的回调中可以拿到结果。
使用方法direct(msg: any, event: string = 'hi')
-
msg
: 消息内容 -
event
: 事件类型
rpc消息不需要指定seq_id,在内部维护了专门的rpc消息队列,所有rpc消息都会进入此队列。
使用示例
bws.direct({name:'zhangsan', age: 18}, 'hi')
.then((res) => {
console.log(res)
})
.catch(err => {
console.log(err)
})
reply
rpc消息的回复服务端可以主动给客户端发送rpc请求(使用场景: 如服务端请求客户端获取地理位置,客户端通过浏览器或其他方式api获取到地址后回复给后端)。
客户端通过bws.processors.rpc_message
函数处理器进行消息的监听,当获取到合适的消息可以使用reply
方法进行回复
reply
第二个参数为参数中接收过来的msg,用来确定回复是针对哪条消息进行的。
使用示例
// 处理hi事件的rpc消息
bws.processors.rpc_message.use((msg) => {
if(msg.event === 'hi') {
bws.reply("hello world", msg)
}
})
bws的其他方法或属性
-
bws.close()
: 断开websocket连接 -
bws.connectStatus
: 获取当前连接状态enum BetterWSStatus { NO_SOCKET = -1, // 未创建WebSocket对象 CONNECTING = 0, OPEN = 1, CLOSING = 2, CLOSED = 3 }
-
bws.connectStatusDesc
: 连接状态的描述,上述enum的key -
bws.updateConfig(config: BetterWSConfig)
: 动态更新配置项,例如需要动态更新protocols,可以通过bws.updateConfig({protocols: ['newprotocols']})
进行更新配置