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