feat: ws 原生版本无法带hearde

This commit is contained in:
TsMask
2024-01-24 16:07:21 +08:00
parent 9eed8ea78d
commit 4572c2060d

164
src/plugins/ws-websocket.ts Normal file
View File

@@ -0,0 +1,164 @@
import { sessionGet } from "@/utils/cache-session-utils";
/**连接参数类型 */
export type TypeParams = {
/**WebSocket服务器将响应的URL */
url?: string;
/**onopen事件的回调函数 */
onopen?: Function;
/**message事件的回调函数 */
onmessage: Function;
/**error事件的回调函数 */
onerror: Function;
/**close事件的回调函数 */
onclose?: Function;
/**心跳周期 若为0则不启用 */
heartTimer?: number;
/**重连等待 若为0则不启用 */
reconnectTimer?: number;
};
/**
* WebSocket 使用方法
*
* import WS from '@/plugins/ws-websocket.ts';
* const options = {
* url: 'ws://127.0.0.1:8080',
* onmessage: (res) => {
* // 接收数据后回调
* },
* // 保活周期 10s
* timer: 10000,
* // 断线重连
* reconnect: true,
* };
* const ws = new WS(options);
*
* 手动关闭
* ws.close();
*/
export class WS {
/**ws 实例 */
private ws: WebSocket | null = null;
/**ws 连接参数 */
private params: TypeParams | null = null;
/**心跳调度器 */
private heartInterval: number = 0;
/**重连定时器 */
private reconnectTimeout: number = 0;
/**
* 构造函数
* @param {object} params 构造函数参数
*/
constructor(params: TypeParams) {
if (!window.WebSocket) {
// 检测浏览器支持
console.error('抱歉! 浏览器不支持websocket');
return;
}
this.params = params;
this.create(params);
}
/**
* 创建链接
* @param {object} params 连接参数
*/
public create(params: TypeParams) {
try {
if (!params.url) {
// 兼容旧前端可改配置文件
const baseUrl = import.meta.env.PROD
? sessionGet('wsUrl') || import.meta.env.VITE_API_BASE_URL
: import.meta.env.VITE_API_BASE_URL;
params.url = `ws://${baseUrl}/ws`;
}
const ws = new WebSocket(params.url);
// 用于指定连接成功后的回调函数。
ws.onopen = ev => {
if (params.heartTimer && params.heartTimer > 0) {
this.heartCheck(params.heartTimer);
}
if (typeof params.onopen === 'function') {
params.onopen(ev);
}
};
// 用于指定当从服务器接受到信息时的回调函数。
ws.onmessage = ev => {
if (typeof params.onmessage === 'function') {
params.onmessage(ev);
}
};
// 用于指定连接关闭后的回调函数。
ws.onclose = ev => {
if (typeof params.onclose === 'function') {
params.onclose(ev);
}
};
// 用于指定连接失败后的回调函数。
ws.onerror = ev => {
console.error('websocket 连接异常', ev);
if (typeof params.onerror === 'function') {
params.onerror(ev);
}
if (params.reconnectTimer && params.reconnectTimer > 0) {
this.reconnect(params.reconnectTimer);
}
};
this.ws = ws;
} catch (error) {
if (typeof params.onerror === 'function') {
params.onerror(error);
}
if (params.reconnectTimer && params.reconnectTimer > 0) {
this.reconnect(params.reconnectTimer);
}
}
}
// 发送消息
send(data: Record<string, any>) {
if (!this.ws) {
console.warn('websocket 不可用');
return;
}
console.log(' readyState', this.ws.readyState);
this.ws.send(JSON.stringify(data));
}
// 手动关闭socket
close() {
this.heartInterval && clearInterval(this.heartInterval);
this.reconnectTimeout && clearTimeout(this.reconnectTimeout);
if (!this.ws) {
console.warn('websocket 不可用');
return;
}
this.ws.close(WebSocket.CLOSED);
}
// 周期性发送ping 保活
heartCheck(heartTimer: number) {
this.heartInterval = window.setInterval(() => {
this.send({
type: 'ping',
});
}, heartTimer);
}
// 断线重连
reconnect(reconnectTimer: number) {
if (this.reconnectTimeout > 0) return;
clearTimeout(this.reconnectTimeout);
this.reconnectTimeout = window.setTimeout(() => {
if (this.params) {
this.create(this.params);
this.reconnectTimeout = 0;
}
}, reconnectTimer);
}
}