From 7536eab077080f072217dd266b61530c0bce7960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Tue, 14 May 2019 21:48:49 +0200 Subject: [PATCH] ready option in attach addon v3 and demo --- demo/client.ts | 4 ++-- demo/server.js | 14 ++++++-------- src/addons/attach/attach.ts | 20 +++++++++++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/demo/client.ts b/demo/client.ts index 0178940243..724ceeb6cd 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -154,8 +154,8 @@ function runRealTerminal(): void { * To run it with UTF8 binary transport, swap comment on * the lines below. (Must also be switched in server.js) */ - term.loadAddon(new AttachAddon(socket)); - // term.loadAddon(new AttachAddon(socket, {inputUtf8: true})); + term.loadAddon(new AttachAddon(socket, {sendReady: true})); + // term.loadAddon(new AttachAddon(socket, {sendReady: true, inputUtf8: true})); term._initialized = true; } diff --git a/demo/server.js b/demo/server.js index e34734007d..0640c51579 100644 --- a/demo/server.js +++ b/demo/server.js @@ -108,15 +108,13 @@ function startServer() { } const send = USE_BINARY_UTF8 ? bufferUtf8(ws, 5) : buffer(ws, 5); - term.on('data', function(data) { - try { - send(data); - } catch (ex) { - // The WebSocket is not open, ignore + ws.once('message', msg => { + // wait once for READY message at the beginning + if (msg !== '#READY#') { + throw new Error(`excepted "#READY#" as first message, but got "${msg}"`); } - }); - ws.on('message', function(msg) { - term.write(msg); + ws.on('message', msg => term.write(msg)); + term.on('data', data => send(data)); }); ws.on('close', function () { term.kill(); diff --git a/src/addons/attach/attach.ts b/src/addons/attach/attach.ts index 2c8a5d4d21..66579b1fea 100644 --- a/src/addons/attach/attach.ts +++ b/src/addons/attach/attach.ts @@ -8,6 +8,8 @@ import { Terminal, IDisposable } from 'xterm'; import { IAttachAddonTerminal } from './Interfaces'; +const READY_MSG = '#READY#'; + /** * Attaches the given terminal to the given socket. * @@ -16,8 +18,9 @@ import { IAttachAddonTerminal } from './Interfaces'; * @param bidirectional Whether the terminal should send data to the socket as well. * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum * frequency of 1 rendering per 10ms. + * @param buffered Whether the addon should send '#READY#' on startup */ -export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void { +export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean, sendReady: boolean): void { const addonTerminal = term; bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional; addonTerminal.__socket = socket; @@ -96,6 +99,16 @@ export function attach(term: Terminal, socket: WebSocket, bidirectional: boolean addonTerminal._core.register(addSocketListener(socket, 'close', () => detach(addonTerminal, socket))); addonTerminal._core.register(addSocketListener(socket, 'error', () => detach(addonTerminal, socket))); + + if (sendReady) { + if (this._socket.readyState === 1) { + // connection already opened, send right away + socket.send(READY_MSG); + } else if (this._socket.readyState === 0) { + // still connecting, thus wait for open event + addSocketListener(socket, 'open', () => socket.send(READY_MSG)); + } + } } function addSocketListener(socket: WebSocket, type: string, handler: (this: WebSocket, ev: Event) => any): IDisposable { @@ -141,9 +154,10 @@ export function apply(terminalConstructor: typeof Terminal): void { * @param bidirectional Whether the terminal should send data to the socket as well. * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum * frequency of 1 rendering per 10ms. + * @param buffered Whether the addon should send '#READY#' on startup */ - (terminalConstructor.prototype).attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void { - attach(this, socket, bidirectional, buffered); + (terminalConstructor.prototype).attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean, sendReady: boolean): void { + attach(this, socket, bidirectional, buffered, sendReady); }; /**