feat: ws 封装工具测试
This commit is contained in:
@@ -1,13 +1,19 @@
|
|||||||
import { sessionGet } from "@/utils/cache-session-utils";
|
import { sessionGet } from '@/utils/cache-session-utils';
|
||||||
|
import { getToken } from './auth-token';
|
||||||
|
import { localGet } from '@/utils/cache-local-utils';
|
||||||
|
import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants';
|
||||||
|
import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants';
|
||||||
|
|
||||||
/**连接参数类型 */
|
/**连接参数类型 */
|
||||||
export type TypeParams = {
|
export type OptionsType = {
|
||||||
/**WebSocket服务器将响应的URL */
|
/**WebSocket服务器将响应的URL */
|
||||||
url?: string;
|
url?: string;
|
||||||
|
/**地址栏参数 */
|
||||||
|
params?: Record<string, string | number | boolean | undefined>;
|
||||||
/**onopen事件的回调函数 */
|
/**onopen事件的回调函数 */
|
||||||
onopen?: Function;
|
onopen?: Function;
|
||||||
/**message事件的回调函数 */
|
/**message事件的回调函数 */
|
||||||
onmessage: Function;
|
onmessage: (data: Record<string, any>) => void;
|
||||||
/**error事件的回调函数 */
|
/**error事件的回调函数 */
|
||||||
onerror: Function;
|
onerror: Function;
|
||||||
/**close事件的回调函数 */
|
/**close事件的回调函数 */
|
||||||
@@ -41,7 +47,7 @@ export class WS {
|
|||||||
/**ws 实例 */
|
/**ws 实例 */
|
||||||
private ws: WebSocket | null = null;
|
private ws: WebSocket | null = null;
|
||||||
/**ws 连接参数 */
|
/**ws 连接参数 */
|
||||||
private params: TypeParams | null = null;
|
private options: OptionsType | null = null;
|
||||||
/**心跳调度器 */
|
/**心跳调度器 */
|
||||||
private heartInterval: number = 0;
|
private heartInterval: number = 0;
|
||||||
/**重连定时器 */
|
/**重连定时器 */
|
||||||
@@ -51,87 +57,135 @@ export class WS {
|
|||||||
* 构造函数
|
* 构造函数
|
||||||
* @param {object} params 构造函数参数
|
* @param {object} params 构造函数参数
|
||||||
*/
|
*/
|
||||||
constructor(params: TypeParams) {
|
constructor(options: OptionsType) {
|
||||||
if (!window.WebSocket) {
|
if (!window.WebSocket) {
|
||||||
// 检测浏览器支持
|
// 检测浏览器支持
|
||||||
console.error('抱歉! 浏览器不支持websocket');
|
console.error('抱歉! 浏览器不支持websocket');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.params = params;
|
this.options = options;
|
||||||
this.create(params);
|
this.create(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建链接
|
* 创建链接
|
||||||
* @param {object} params 连接参数
|
* @param {object} options 连接参数
|
||||||
*/
|
*/
|
||||||
public create(params: TypeParams) {
|
public create(options: OptionsType) {
|
||||||
try {
|
try {
|
||||||
if (!params.url) {
|
if (!options.url) {
|
||||||
// 兼容旧前端可改配置文件
|
// 兼容旧前端可改配置文件
|
||||||
const baseUrl = import.meta.env.PROD
|
const wsUrl = import.meta.env.PROD
|
||||||
? sessionGet('wsUrl') || import.meta.env.VITE_API_BASE_URL
|
? sessionGet('wsUrl') || import.meta.env.VITE_API_BASE_URL
|
||||||
: import.meta.env.VITE_API_BASE_URL;
|
: '/socket';
|
||||||
params.url = `ws://${baseUrl}/ws`;
|
if (wsUrl.startsWith('ws')) {
|
||||||
|
options.url = `${wsUrl}/ws`;
|
||||||
|
} else if (wsUrl.startsWith('https')) {
|
||||||
|
options.url = `${wsUrl.replace('https', 'wss')}/ws`;
|
||||||
|
} else if (wsUrl.startsWith('http')) {
|
||||||
|
options.url = `${wsUrl.replace('http', 'ws')}/ws`;
|
||||||
|
} else {
|
||||||
|
const protocol =
|
||||||
|
window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||||
|
options.url = `${protocol}${location.host}${wsUrl}/ws`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 地址栏参数
|
||||||
|
let params = options.params || {};
|
||||||
|
// 设置 token
|
||||||
|
const token = getToken();
|
||||||
|
if (token) {
|
||||||
|
params[TOKEN_RESPONSE_FIELD] = token;
|
||||||
|
}
|
||||||
|
// 多语言处理
|
||||||
|
params['language'] = localGet(CACHE_LOCAL_I18N) || 'en_US';
|
||||||
|
let paramStr = '';
|
||||||
|
for (const key in params) {
|
||||||
|
const value = params[key];
|
||||||
|
// 空字符或未定义的值不作为参数发送
|
||||||
|
if (value === '' || value === undefined) continue;
|
||||||
|
paramStr += `&${encodeURIComponent(key)}=${encodeURIComponent(
|
||||||
|
value
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
if (paramStr && paramStr.startsWith('&')) {
|
||||||
|
options.url = `${options.url}?${paramStr.substring(1)}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ws = new WebSocket(params.url);
|
const ws = new WebSocket(options.url, 'omc-ws');
|
||||||
// 用于指定连接成功后的回调函数。
|
// 用于指定连接成功后的回调函数。
|
||||||
ws.onopen = ev => {
|
ws.onopen = ev => {
|
||||||
if (params.heartTimer && params.heartTimer > 0) {
|
if (options.heartTimer && options.heartTimer > 0) {
|
||||||
this.heartCheck(params.heartTimer);
|
this.heartCheck(options.heartTimer);
|
||||||
}
|
}
|
||||||
if (typeof params.onopen === 'function') {
|
if (typeof options.onopen === 'function') {
|
||||||
params.onopen(ev);
|
options.onopen(ev);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 用于指定当从服务器接受到信息时的回调函数。
|
// 用于指定当从服务器接受到信息时的回调函数。
|
||||||
ws.onmessage = ev => {
|
ws.onmessage = ev => {
|
||||||
if (typeof params.onmessage === 'function') {
|
const data = ev.data;
|
||||||
params.onmessage(ev);
|
// 解析文本消息
|
||||||
|
if (ev.type === 'message') {
|
||||||
|
try {
|
||||||
|
const jsonData = JSON.parse(data);
|
||||||
|
if (typeof options.onmessage === 'function') {
|
||||||
|
options.onmessage(jsonData);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('websocket 消息格式错误', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 用于指定连接关闭后的回调函数。
|
// 用于指定连接关闭后的回调函数。
|
||||||
ws.onclose = ev => {
|
ws.onclose = ev => {
|
||||||
if (typeof params.onclose === 'function') {
|
if (typeof options.onclose === 'function') {
|
||||||
params.onclose(ev);
|
options.onclose(ev);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 用于指定连接失败后的回调函数。
|
// 用于指定连接失败后的回调函数。
|
||||||
ws.onerror = ev => {
|
ws.onerror = ev => {
|
||||||
console.error('websocket 连接异常', ev);
|
console.error('websocket 连接异常', ev);
|
||||||
|
|
||||||
if (typeof params.onerror === 'function') {
|
if (typeof options.onerror === 'function') {
|
||||||
params.onerror(ev);
|
options.onerror(ev);
|
||||||
}
|
}
|
||||||
if (params.reconnectTimer && params.reconnectTimer > 0) {
|
if (options.reconnectTimer && options.reconnectTimer > 0) {
|
||||||
this.reconnect(params.reconnectTimer);
|
this.reconnect(options.reconnectTimer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.ws = ws;
|
this.ws = ws;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (typeof params.onerror === 'function') {
|
if (typeof options.onerror === 'function') {
|
||||||
params.onerror(error);
|
options.onerror(error);
|
||||||
}
|
}
|
||||||
if (params.reconnectTimer && params.reconnectTimer > 0) {
|
if (options.reconnectTimer && options.reconnectTimer > 0) {
|
||||||
this.reconnect(params.reconnectTimer);
|
this.reconnect(options.reconnectTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送消息
|
// 发送消息
|
||||||
send(data: Record<string, any>) {
|
public send(data: Record<string, any>) {
|
||||||
if (!this.ws) {
|
if (!this.ws) {
|
||||||
console.warn('websocket 不可用');
|
console.warn('websocket 不可用');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log(' readyState', this.ws.readyState);
|
console.log(' readyState', this.ws.readyState);
|
||||||
|
if (
|
||||||
|
this.ws.readyState === WebSocket.CLOSED ||
|
||||||
|
this.ws.readyState === WebSocket.CLOSING
|
||||||
|
) {
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.ws.send(JSON.stringify(data));
|
this.ws.send(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 手动关闭socket
|
// 手动关闭socket
|
||||||
close() {
|
public close() {
|
||||||
this.heartInterval && clearInterval(this.heartInterval);
|
this.heartInterval && clearInterval(this.heartInterval);
|
||||||
this.reconnectTimeout && clearTimeout(this.reconnectTimeout);
|
this.reconnectTimeout && clearTimeout(this.reconnectTimeout);
|
||||||
if (!this.ws) {
|
if (!this.ws) {
|
||||||
@@ -142,7 +196,7 @@ export class WS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 周期性发送ping 保活
|
// 周期性发送ping 保活
|
||||||
heartCheck(heartTimer: number) {
|
private heartCheck(heartTimer: number) {
|
||||||
this.heartInterval = window.setInterval(() => {
|
this.heartInterval = window.setInterval(() => {
|
||||||
this.send({
|
this.send({
|
||||||
type: 'ping',
|
type: 'ping',
|
||||||
@@ -151,12 +205,12 @@ export class WS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 断线重连
|
// 断线重连
|
||||||
reconnect(reconnectTimer: number) {
|
private reconnect(reconnectTimer: number) {
|
||||||
if (this.reconnectTimeout > 0) return;
|
if (this.reconnectTimeout > 0) return;
|
||||||
clearTimeout(this.reconnectTimeout);
|
clearTimeout(this.reconnectTimeout);
|
||||||
this.reconnectTimeout = window.setTimeout(() => {
|
this.reconnectTimeout = window.setTimeout(() => {
|
||||||
if (this.params) {
|
if (this.options) {
|
||||||
this.create(this.params);
|
this.create(this.options);
|
||||||
this.reconnectTimeout = 0;
|
this.reconnectTimeout = 0;
|
||||||
}
|
}
|
||||||
}, reconnectTimer);
|
}, reconnectTimer);
|
||||||
|
|||||||
@@ -13,10 +13,29 @@ import { ColumnsType } from 'ant-design-vue/lib/table/Table';
|
|||||||
import { message } from 'ant-design-vue/lib';
|
import { message } from 'ant-design-vue/lib';
|
||||||
import { hasPermissions } from '@/plugins/auth-user';
|
import { hasPermissions } from '@/plugins/auth-user';
|
||||||
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
import { RESULT_CODE_SUCCESS } from '@/constants/result-constants';
|
||||||
|
import { WS, OptionsType } from '@/plugins/ws-websocket';
|
||||||
import useI18n from '@/hooks/useI18n';
|
import useI18n from '@/hooks/useI18n';
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
onMounted(() => {
|
||||||
onMounted(() => {});
|
const options: OptionsType = {
|
||||||
|
params: {
|
||||||
|
subGroupID: '1005',
|
||||||
|
},
|
||||||
|
onmessage: ev => {
|
||||||
|
// 接收数据后回调
|
||||||
|
console.log(ev);
|
||||||
|
},
|
||||||
|
onerror: (ev: any) => {
|
||||||
|
// 接收数据后回调
|
||||||
|
console.log(ev);
|
||||||
|
},
|
||||||
|
// 保活周期 10s
|
||||||
|
heartTimer: 0,
|
||||||
|
// 断线重连
|
||||||
|
reconnectTimer: 0,
|
||||||
|
};
|
||||||
|
const ws = new WS(options);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -25,6 +25,13 @@ export default defineConfig(({ mode }) => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: p => p.replace(env.VITE_API_BASE_URL, ''),
|
rewrite: p => p.replace(env.VITE_API_BASE_URL, ''),
|
||||||
},
|
},
|
||||||
|
// 代理 websockets
|
||||||
|
'/socket': {
|
||||||
|
target: 'ws://192.168.5.58:3040',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: p => p.replace('/socket', ''),
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
Reference in New Issue
Block a user