UNPKG

@eclipse-ditto/ditto-javascript-client-dom

Version:

DOM implementation of Eclipse Ditto JavaScript API to be used in browsers.

117 lines 4.16 kB
/*! * Copyright (c) 2019 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0 * * SPDX-License-Identifier: EPL-2.0 */ import { authenticateWithUrl } from '../../api/src/auth/auth-provider'; /** * Browser implementation of a web socket requester. */ export class FetchWebSocket { constructor(webSocket, webSocketUrl, handler, reconnect = true) { this.webSocket = webSocket; this.webSocketUrl = webSocketUrl; this.handler = handler; this.connected = true; this.shouldReconnect = reconnect; this.setHandles(); } /** * Builds an instance of FetchWebSocket. * * @param url - The Url of the service. * @param handler - The handler that gets called for responses from the web socket. * @param authProviders - The auth providers to use. * @param reconnect - Whether to automatically reconnect on connection loss. * @return a Promise for the web socket connection. */ static buildInstance(url, handler, authProviders, reconnect = true) { return new Promise(resolve => { const authenticatedUrl = authenticateWithUrl(url, authProviders); const finalUrl = authenticatedUrl.toString(); const webSocket = new WebSocket(finalUrl); webSocket.addEventListener('open', () => { resolve(new FetchWebSocket(webSocket, finalUrl, handler, reconnect)); }); }); } executeCommand(request) { this.webSocket.send(request); } close(code, reason) { this.shouldReconnect = false; if (this.connected) { this.webSocket.close(code, reason); } } /** * Reestablishes a failed web socket connection. * * @param retry - The amount of time to wait to reconnect. * @return a Promise for the reestablished web socket connection. */ reconnect(retry) { if (this.shouldReconnect) { return new Promise((resolve, reject) => { this.webSocket = new WebSocket(this.webSocketUrl); this.webSocket.addEventListener('open', () => { this.connected = true; this.setHandles(); resolve(this); }); setTimeout(() => { if (this.connected) { return; } if (retry <= 120000) { console.log('Reconnect failed! Trying again!'); resolve(this.reconnect(retry * 2)); } console.log('Reconnect failed!'); reject('Reconnect failed: Timed out'); }, retry); }); } else { return Promise.reject('Reconnect disabled'); } } /** * Sets up the handler so it receives events from the web socket. */ setHandles() { this.webSocket.addEventListener('message', event => { this.handler.handleInput(event.data); }); this.webSocket.addEventListener('close', () => { this.connected = false; this.handler.handleClose(Promise.resolve(this.reconnect(1000))); }); this.webSocket.addEventListener('error', event => { this.handler.handleError(`WebSocket: ${event}`); }); } } /** * Builder for the Browser implementation of a web socket. */ export class FetchWebSocketBuilder { constructor() { } withHandler(handler, reconnect = true) { return FetchWebSocket.buildInstance(this.dittoUrl, handler, this.authProviders, reconnect); } withConnectionDetails(url, authProviders) { this.authProviders = authProviders; this.dittoUrl = url; return this; } } //# sourceMappingURL=fetch-websocket.js.map