@eclipse-ditto/ditto-javascript-client-dom
Version:
DOM implementation of Eclipse Ditto JavaScript API to be used in browsers.
117 lines • 4.16 kB
JavaScript
/*!
* 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