fix: 看板ws模块接入
This commit is contained in:
@@ -6,18 +6,18 @@ import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants';
|
||||
|
||||
/**连接参数类型 */
|
||||
export type OptionsType = {
|
||||
/**WebSocket服务器将响应的URL */
|
||||
url?: string;
|
||||
/**WebSocket服务地址 */
|
||||
url: string;
|
||||
/**地址栏参数 */
|
||||
params?: Record<string, string | number | boolean | undefined>;
|
||||
/**onopen事件的回调函数 */
|
||||
onopen?: Function;
|
||||
onopen?: () => void;
|
||||
/**message事件的回调函数 */
|
||||
onmessage: (data: Record<string, any>) => void;
|
||||
/**error事件的回调函数 */
|
||||
onerror: Function;
|
||||
/**close事件的回调函数 */
|
||||
onclose?: Function;
|
||||
onclose?: (code: number) => void;
|
||||
/**心跳周期 若为0则不启用 */
|
||||
heartTimer?: number;
|
||||
/**重连等待 若为0则不启用 */
|
||||
@@ -28,17 +28,12 @@ export type OptionsType = {
|
||||
* 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);
|
||||
*
|
||||
* const ws = new WS();
|
||||
*
|
||||
* 创建连接
|
||||
* const options: OptionsType = { };
|
||||
* ws.connect(options);
|
||||
*
|
||||
* 手动关闭
|
||||
* ws.close();
|
||||
@@ -57,60 +52,59 @@ export class WS {
|
||||
* 构造函数
|
||||
* @param {object} params 构造函数参数
|
||||
*/
|
||||
constructor(options: OptionsType) {
|
||||
constructor(options?: OptionsType) {
|
||||
if (!window.WebSocket) {
|
||||
// 检测浏览器支持
|
||||
console.error('抱歉! 浏览器不支持websocket');
|
||||
console.error('Sorry! Browser does not support websocket');
|
||||
return;
|
||||
}
|
||||
this.options = options;
|
||||
this.create(options);
|
||||
options && this.connect(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建链接
|
||||
* @param {object} options 连接参数
|
||||
*/
|
||||
public create(options: OptionsType) {
|
||||
public connect(options: OptionsType) {
|
||||
this.options = options;
|
||||
try {
|
||||
if (!options.url) {
|
||||
if (!options.url.startsWith('ws')) {
|
||||
const uri = options.url.startsWith('/')
|
||||
? options.url
|
||||
: `/${options.url}`;
|
||||
// 兼容旧前端可改配置文件
|
||||
const wsUrl = import.meta.env.PROD
|
||||
? sessionGet('wsUrl') || import.meta.env.VITE_API_BASE_URL
|
||||
: '/socket';
|
||||
if (wsUrl.startsWith('ws')) {
|
||||
options.url = `${wsUrl}/ws`;
|
||||
options.url = `${wsUrl}${uri}`;
|
||||
} else if (wsUrl.startsWith('https')) {
|
||||
options.url = `${wsUrl.replace('https', 'wss')}/ws`;
|
||||
options.url = `${wsUrl.replace('https', 'wss')}${uri}`;
|
||||
} else if (wsUrl.startsWith('http')) {
|
||||
options.url = `${wsUrl.replace('http', 'ws')}/ws`;
|
||||
options.url = `${wsUrl.replace('http', 'ws')}${uri}`;
|
||||
} else {
|
||||
const protocol =
|
||||
window.location.protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
options.url = `${protocol}${location.host}${wsUrl}/ws`;
|
||||
options.url = `${protocol}${location.host}${wsUrl}${uri}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 地址栏参数
|
||||
let params = options.params || {};
|
||||
// 地址栏参数
|
||||
let params = Object.assign({}, 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)}`;
|
||||
}
|
||||
[TOKEN_RESPONSE_FIELD]: getToken(),
|
||||
// 多语言
|
||||
['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(options.url, 'omc-ws');
|
||||
@@ -120,33 +114,33 @@ export class WS {
|
||||
this.heartCheck(options.heartTimer);
|
||||
}
|
||||
if (typeof options.onopen === 'function') {
|
||||
options.onopen(ev);
|
||||
options.onopen();
|
||||
}
|
||||
};
|
||||
// 用于指定当从服务器接受到信息时的回调函数。
|
||||
ws.onmessage = ev => {
|
||||
const data = ev.data;
|
||||
// 解析文本消息
|
||||
if (ev.type === 'message') {
|
||||
const data = ev.data;
|
||||
try {
|
||||
const jsonData = JSON.parse(data);
|
||||
if (typeof options.onmessage === 'function') {
|
||||
options.onmessage(jsonData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('websocket 消息格式错误', error);
|
||||
console.error('websocket message formatting error', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
// 用于指定连接关闭后的回调函数。
|
||||
ws.onclose = ev => {
|
||||
if (typeof options.onclose === 'function') {
|
||||
options.onclose(ev);
|
||||
options.onclose(ev.code);
|
||||
}
|
||||
};
|
||||
// 用于指定连接失败后的回调函数。
|
||||
ws.onerror = ev => {
|
||||
console.error('websocket 连接异常', ev);
|
||||
console.error('websocket connection anomaly', ev);
|
||||
|
||||
if (typeof options.onerror === 'function') {
|
||||
options.onerror(ev);
|
||||
@@ -169,7 +163,7 @@ export class WS {
|
||||
// 发送消息
|
||||
public send(data: Record<string, any>) {
|
||||
if (!this.ws) {
|
||||
console.warn('websocket 不可用');
|
||||
console.warn('websocket unavailable');
|
||||
return;
|
||||
}
|
||||
console.log(' readyState', this.ws.readyState);
|
||||
@@ -189,16 +183,17 @@ export class WS {
|
||||
this.heartInterval && clearInterval(this.heartInterval);
|
||||
this.reconnectTimeout && clearTimeout(this.reconnectTimeout);
|
||||
if (!this.ws) {
|
||||
console.warn('websocket 不可用');
|
||||
console.warn('websocket unavailable');
|
||||
return;
|
||||
}
|
||||
this.ws.close(WebSocket.CLOSED);
|
||||
this.ws.close(1000, 'user initiated closure');
|
||||
}
|
||||
|
||||
// 周期性发送ping 保活
|
||||
private heartCheck(heartTimer: number) {
|
||||
this.heartInterval = window.setInterval(() => {
|
||||
this.send({
|
||||
requestId: `${Date.now()}`,
|
||||
type: 'ping',
|
||||
});
|
||||
}, heartTimer);
|
||||
@@ -210,7 +205,7 @@ export class WS {
|
||||
clearTimeout(this.reconnectTimeout);
|
||||
this.reconnectTimeout = window.setTimeout(() => {
|
||||
if (this.options) {
|
||||
this.create(this.options);
|
||||
this.connect(this.options);
|
||||
this.reconnectTimeout = 0;
|
||||
}
|
||||
}, reconnectTimer);
|
||||
|
||||
Reference in New Issue
Block a user