UNPKG

@cloudpss/ubrpc

Version:

79 lines 2.73 kB
import { WebSocket } from '@cloudpss/fetch'; import { v4 } from 'uuid'; import { waitAuth } from './auth.js'; import { RpcSocket } from './socket.js'; import { send } from './utils/messaging.js'; import { VERSION } from './version.js'; import { logger } from './logger.js'; const INIT_RECONNECT_TIMEOUT = 250; const MAX_RECONNECT_TIMEOUT = 10000; /** 由 WS Client 建立的 RPC 连接 */ export class RpcClientSocket extends RpcSocket { /** 建立连接使用的 WebSocket 实现 */ static { this.WebSocket = null; } constructor(url, metadata, local) { super(v4()); this.#local = local; this._localMetadata = metadata; this.url = typeof url == 'string' ? url : url.href; this.seq = 2; logger('[%s] client socket created. url=', this.id, this.url); this.connect(); } #local; /** @inheritdoc */ get local() { return this.#local; } /** 等待连接成功或失败 */ get connected() { return Promise.resolve(this.ready.value); } /** @inheritdoc */ async authSocket() { logger('[%s] authenticating...', this.id); const { socket } = this; const seq = this.nextSeq(); send(socket, 'auth', { seq, id: this.id, version: VERSION, metadata: this.localMetadata ?? {}, }); const metadata = (await waitAuth(socket, seq, this.id))[2]; logger('[%s] authenticated. remoteMeta=%o', this.id, metadata); return metadata; } #reconnectTimeout = INIT_RECONNECT_TIMEOUT; /** @inheritdoc */ onClose(ev) { super.onClose(ev); if (this.destroyed) return; logger('[%s] reconnecting in %dms...', this.id, this.#reconnectTimeout); setTimeout(() => { this.connect(); }, this.#reconnectTimeout); } /** 建立连接 */ connect() { const socket = new (this.constructor.WebSocket ?? WebSocket)(this.url); socket.binaryType = 'arraybuffer'; this.socket = socket; logger('[%s] connecting...', this.id); this.connected.then(() => { logger('[%s] connected.', this.id); this.#reconnectTimeout = INIT_RECONNECT_TIMEOUT; }, () => { if (this.destroyed) return; this.resetReady(); this.#reconnectTimeout = Math.min(this.#reconnectTimeout * 2, MAX_RECONNECT_TIMEOUT); logger('[%s] connect failed. retrying in %dms...', this.id, this.#reconnectTimeout); setTimeout(() => { this.connect(); }, this.#reconnectTimeout); }); } } //# sourceMappingURL=client.js.map