UNPKG

@skyway-sdk/core

Version:

The official Next Generation JavaScript SDK for SkyWay

221 lines 9.2 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SignalingSession = exports.setupSignalingSession = void 0; const common_1 = require("@skyway-sdk/common"); const signaling_client_1 = require("@skyway-sdk/signaling-client"); const token_1 = require("@skyway-sdk/token"); const errors_1 = require("../errors"); const util_1 = require("../util"); const log = new common_1.Logger('packages/core/src/external/signaling.ts'); function setupSignalingSession(context, channel, memberDto) { return __awaiter(this, void 0, void 0, function* () { const { signalingService } = context.config; const client = new signaling_client_1.SignalingClient({ token: context.authTokenString, channelId: channel.id, channelName: channel.name, memberId: memberDto.id, memberName: memberDto.name, }, { logger: { error: (error) => __awaiter(this, void 0, void 0, function* () { log.error('SignalingClient error', (0, util_1.createError)({ operationName: 'SignalingClient.logger', context, info: Object.assign(Object.assign({}, errors_1.errors.internal), { detail: 'signalingClient error' }), error, path: log.prefix, channel, })); }), debug: () => { }, }, signalingServerDomain: signalingService.domain, secure: signalingService.secure, }); const signalingSession = new SignalingSession(client, context); yield signalingSession.connect(); return signalingSession; }); } exports.setupSignalingSession = setupSignalingSession; class SignalingSession { constructor(_client, context) { this._client = _client; this.context = context; this.onConnectionFailed = new common_1.Event(); this.onConnectionStateChanged = new common_1.Event(); this.onMessage = new common_1.Event(); this.closed = false; this._chunkedMessageBuffer = {}; this._backoffUpdateSkyWayAuthToken = new common_1.BackOff({ times: 8, interval: 100, jitter: 100, }); this._disposer = new common_1.EventDisposer(); this._listen(); context.onTokenUpdated .add((token) => __awaiter(this, void 0, void 0, function* () { yield this._updateSkyWayAuthToken(token); })) .disposer(this._disposer); } updateClient(client) { this._client = client; this._listen(); } _listen() { this._client.onConnectionFailed.addOneTimeListener(() => { this.onConnectionFailed.emit({}); }); this._client.onConnectionStateChanged.addListener((state) => { log.debug('signalingClient onConnectionStateChanged', state); this.onConnectionStateChanged.emit(state); }); this._client.onRequested.addListener(({ data, src, reply }) => __awaiter(this, void 0, void 0, function* () { var _a; const messageChunk = data; const { chunk, length, offset, id, type } = messageChunk; if (type !== messageType) return; if (length === 0) { this.onMessage.emit({ src, data: JSON.parse(chunk), }); } else { this._chunkedMessageBuffer[id] = [ ...((_a = this._chunkedMessageBuffer[id]) !== null && _a !== void 0 ? _a : []), messageChunk.chunk, ]; if (length === offset) { const message = this._chunkedMessageBuffer[id].join(''); delete this._chunkedMessageBuffer[id]; this.onMessage.emit({ src, data: JSON.parse(message), }); } } yield reply({}).catch((e) => { if (this.closed) return; log.warn('failed to reply', (0, util_1.createWarnPayload)({ operationName: 'SignalingSession.reply', detail: 'SignalingClient failed to reply', }), e); }); })); } _updateSkyWayAuthToken(token) { return __awaiter(this, void 0, void 0, function* () { if (this._backoffUpdateSkyWayAuthToken.exceeded) { log.error('[failed] updateSkyWayAuthToken'); return; } yield this._backoffUpdateSkyWayAuthToken.wait(); log.debug('[start] updateSkyWayAuthToken', { count: this._backoffUpdateSkyWayAuthToken.count, }); const e = yield this._client .updateSkyWayAuthToken(token) .catch((e) => e); if (e) { log.warn('[retry] updateSkyWayAuthToken', (0, util_1.createWarnPayload)({ operationName: 'SignalingSession._updateSkyWayAuthToken', detail: '[retry] updateSkyWayAuthToken', }), e); yield this._updateSkyWayAuthToken(token); return; } log.debug('[end] updateSkyWayAuthToken'); this._backoffUpdateSkyWayAuthToken.reset(); }); } get connectionState() { return this._client.connectionState; } connect() { return __awaiter(this, void 0, void 0, function* () { log.debug('[start] connect signalingService'); yield this._client.connect().catch((err) => { throw (0, util_1.createError)({ operationName: 'signalingSession.connect', path: log.prefix, info: Object.assign(Object.assign({}, errors_1.errors.internal), { detail: 'signalingClient failed to connect Server' }), context: this.context, error: err, }); }); log.debug('[end] connect signalingService'); }); } close() { this.closed = true; this._disposer.dispose(); this._client.disconnect(); } /**@throws {@link SkyWayError} */ send(target, data, /**ms */ timeout = 10000) { var _a; return __awaiter(this, void 0, void 0, function* () { try { const payload = JSON.stringify(data); const id = (0, token_1.uuidV4)(); // chunking message if (payload.length > 20480) { const split = (_a = payload.match(/.{1,20480}/g)) !== null && _a !== void 0 ? _a : []; let offset = 0; for (const chunk of split) { const chunkMessage = { type: messageType, length: split.length - 1, offset: offset++, chunk, id, }; yield this._client.request(target, chunkMessage, timeout / 1000); } } else { const chunkMessage = { type: messageType, length: 0, offset: 0, chunk: payload, id, }; yield this._client.request(target, chunkMessage, timeout / 1000); } } catch (error) { if (this.closed || target.state !== 'joined') return; throw (0, util_1.createError)({ operationName: 'SignalingSession.send', context: this.context, info: Object.assign(Object.assign({}, errors_1.errors.internal), { detail: 'signalingClient' }), error, path: log.prefix, payload: { target, data }, }); } }); } } exports.SignalingSession = SignalingSession; const messageType = 'signalingMessage'; //# sourceMappingURL=signaling.js.map