UNPKG

open-collaboration-server

Version:

Open Collaboration Server implementation, part of the Open Collaboration Tools project

155 lines 4.77 kB
// ****************************************************************************** // Copyright 2024 TypeFox GmbH // This program and the accompanying materials are made available under the // terms of the MIT License, which is available in the project root. // ****************************************************************************** import { Disposable, Emitter, Encoding, DisposableCollection } from 'open-collaboration-protocol'; export class Channel { onDidCloseEmitter = new Emitter(); onDidDisconnectEmitter = new Emitter(); onDidReconnectEmitter = new Emitter(); onMessageEmitter = new Emitter(); get onClose() { return this.onDidCloseEmitter.event; } get onDisconnect() { return this.onDidDisconnectEmitter.event; } get onReconnect() { return this.onDidReconnectEmitter.event; } get transport() { return this._transport; } set transport(transport) { this.toDispose.dispose(); this._transport = transport; if (transport) { this.toDispose.push(transport.onClose(() => { this.onDidDisconnectEmitter.fire(); this._transport = undefined; })); this.toDispose.push(transport.onMessage(message => { this.onMessageEmitter.fire(message); })); this.onDidReconnectEmitter.fire(); for (const message of this.buffer) { transport.sendMessage(message); } this.buffer = []; } } _transport; // Buffer to store messages that couldn't be sent yet due to a disconnect buffer = []; toDispose = new DisposableCollection(); closeTimeout; constructor(transport) { this._transport = transport; this.toDispose.push(transport.onClose(() => { this.onDidDisconnectEmitter.fire(); this._transport = undefined; })); this.toDispose.push(transport.onMessage(message => { this.onMessageEmitter.fire(message); })); this.onDisconnect(() => { this.closeTimeout = setTimeout(() => { this.close(); }, 30_000); }); this.onReconnect(() => { if (this.closeTimeout) { clearTimeout(this.closeTimeout); this.closeTimeout = undefined; } }); } get onMessage() { return this.onMessageEmitter.event; } sendMessage(message) { if (this._transport) { this._transport.sendMessage(message); } else { this.buffer.push(message); } } close() { this.toDispose.dispose(); this.onDidCloseEmitter.fire(); this.onDidCloseEmitter.dispose(); this.onDidDisconnectEmitter.dispose(); this.onDidReconnectEmitter.dispose(); this.transport?.close(); } } export class WebSocketChannel { onDidCloseEmitter = new Emitter(); get onClose() { return this.onDidCloseEmitter.event; } _socket; constructor(socket) { this._socket = socket; this._socket.onclose = () => { this.onDidCloseEmitter.fire(); }; } onMessage(cb) { const decode = (message) => { const data = Encoding.decode(new Uint8Array(message)); cb(data); }; this._socket.on('message', decode); return Disposable.create(() => { this._socket.off('message', decode); }); } sendMessage(message) { const buffer = Encoding.encode(message); this._socket.send(buffer); } close() { this.onDidCloseEmitter.dispose(); this._socket.close(); } } export class SocketIoChannel { onDidCloseEmitter = new Emitter(); get onClose() { return this.onDidCloseEmitter.event; } _socket; constructor(socket) { this._socket = socket; this._socket.on('disconnect', () => { this.onDidCloseEmitter.fire(); }); } onMessage(cb) { const decode = (message) => { try { const data = Encoding.decode(new Uint8Array(message)); cb(data); } catch (e) { console.error(e); } }; this._socket.on('message', decode); return Disposable.create(() => { this._socket.off('message', decode); }); } sendMessage(message) { const buffer = Encoding.encode(message); this._socket.send(buffer); } close() { this.onDidCloseEmitter.dispose(); this._socket.disconnect(true); } } //# sourceMappingURL=channel.js.map