import { SockJS, Stomp } from '../model/ws.interface'; // import assert from 'assert'; import { isNullOrUndefined } from 'util'; import { trim } from 'lodash'; let assert = require('assert'); (global as any).SockJS = require('../../external-dependency/sockjs.js'); export interface WebsocketOptions { endpoint: string; tokenGenerator: () => string; retry?: number; onConnectSuccess?: (stomp: Stomp) => void, onError?: (error: Error) => void } /** * 需要手动在 index.html 导入 * sock.js, stomp.js */ declare const SockJS: SockJS; declare const Stomp: Stomp; export class WebsocketClient { private stomp: Stomp; private connected = false; constructor(private options: WebsocketOptions) { } connect(options?: WebsocketOptions): Promise { options = options || this.options || {} as any; const { endpoint, tokenGenerator, onConnectSuccess, onError } = options; assert(!!trim(endpoint)); assert(!!tokenGenerator); const sockJS = new SockJS(endpoint); const stomp = this.stomp = Stomp.over(sockJS); stomp.debug = null; stomp.heartbeat.outgoing = 1000; return new Promise((resolve, reject) => { stomp.connect( { Authorization: `Bearer ${tokenGenerator()}` }, (successFrame: any) => { // console.log('stomp connected', successFrame); this.connected = true; resolve(successFrame); onConnectSuccess && onConnectSuccess(stomp); }, (error: Error) => { this.connected = false; reject(error); onError && onError(error); } ); }); } subscribeTopic(topic: string, messageHandler: (message: any) => void): Promise { assert(!isNullOrUndefined(messageHandler)); return new Promise((resolve, reject) => { if (this.connected) { this.stomp.subscribe(topic, (resp: any) => { resolve(resp); try { const message = JSON.parse(resp.body); // TODO: handle non JSON & exception messageHandler(message); } catch (e) { console.error(`${topic} error`, resp, e); reject(e); } }); } else { reject(new Error('websocket 未连接')); } }); } disconnect(onDisconnect?: () => void) { return new Promise((resolve, reject) => { if (this.stomp) { try { this.stomp.disconnect(() => { resolve(true); onDisconnect && onDisconnect(); }); } catch (e) { reject(e); } } else { reject(new Error('stomp 未初始化')); } }); } }