import { Client } from 'ts-linker-sdk'; import { getMetaData } from './meta'; export interface WebSocketClientStatus { created: boolean; connected: boolean; login: boolean; } export interface WebSocketResp { value: object | string; } export type ListenerCallback = (data: WebSocketResp) => void; const meta = getMetaData(); const PING_INTERVAL = 50 * 1000; export class WebSocketClient { client: Client; interval: number; wsUrl: string; token: string; sid: string; chatToken: object; status: WebSocketClientStatus = { created: false, connected: false, login: false }; /** 默认构造函数 */ constructor(wsUrl: string, token: string, sid: string, chatToken: object) { this.wsUrl = wsUrl; this.token = token; this.chatToken = chatToken; this.sid = sid; } async init() { return this.create(); } getStatus() { return this.status; } async create() { const url = this.wsUrl; return new Promise((resolve, reject) => { if (!url) { throw new Error('websocket url is required.'); } this.client = Client.getInstance(url, { onOpen: async () => { try { this.ping(); this.interval = setInterval(() => { this.ping(); }, PING_INTERVAL) as any; } catch (err) { console.error(err); } const data = await this.connect(); await this.authentication(); resolve(data.value); }, onError: () => { resolve(false); }, onClose: () => { clearInterval(this.interval); } }); }); } on(url: string, callback: (data: WebSocketResp) => void) { if (!url) { throw new Error('url is required.'); } this.client.addMessageListener(url, callback); } off(url: string) { this.client.removeMessageListener(url); } async request(url: string, data: object) { return this.client.request(url, data); } async connect() { const { sid } = this; if (sid) { this.client.setRequestProperty('sid', sid); } const data = await this.request('/v1/session/start', { ...this.chatToken, ...meta }); if (data && data.value) { const id = data.value as string; this.sid = id; this.client.setRequestProperty('sid', id); } return data || true; } ping() { return this.client.ping({}); } async authentication() { const tk = this.token; const data = this.request('/v1/session/bind/uid/by/token', { token: tk }); return data || true; } onMessage(callback: ListenerCallback) { this.on('/v1/message/listener', callback); } sendMessage(data: object) { return this.request('/v1/send/message', data); } markServiced(data: object) { return this.request('/v1/mark/message/serviced', data); } /** * * @param {*} data contact_id chat_type start_time limit */ getHistoryMessage(data: object) { return this.request('/v1/history/message', data); } }