feat: ws 原生版本无法带hearde
This commit is contained in:
164
src/plugins/ws-websocket.ts
Normal file
164
src/plugins/ws-websocket.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user