diff --git a/src/vs/base/parts/ipc/common/ipc.mp.ts b/src/vs/base/parts/ipc/common/ipc.mp.ts index 8e59b5db9bfa698f3ed3b40b74633f94f2c85c01..01c36e6351da91752cb449c0fa9f7ba2d7d62941 100644 --- a/src/vs/base/parts/ipc/common/ipc.mp.ts +++ b/src/vs/base/parts/ipc/common/ipc.mp.ts @@ -17,13 +17,10 @@ import { VSBuffer } from 'vs/base/common/buffer'; export interface MessageEvent { /** - * For our use we only consider `Uint8Array` and `disconnect` - * a valid data transfer via message ports. Our protocol - * implementation is buffer based and we only need the explicit - * `disconnect` because message ports currently have no way of - * indicating when their connection is closed. + * For our use we only consider `Uint8Array` a valid data transfer + * via message ports because our protocol implementation is buffer based. */ - data: Uint8Array | 'disconnect'; + data: Uint8Array; } export interface MessagePort { @@ -31,7 +28,7 @@ export interface MessagePort { addEventListener(type: 'message', listener: (this: MessagePort, e: MessageEvent) => unknown): void; removeEventListener(type: 'message', listener: (this: MessagePort, e: MessageEvent) => unknown): void; - postMessage(message: Uint8Array | 'disconnect'): void; + postMessage(message: Uint8Array): void; start(): void; close(): void; @@ -44,19 +41,12 @@ export interface MessagePort { */ export class Protocol implements IMessagePassingProtocol { - private readonly onRawData = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => e.data === 'disconnect' ? e.data : VSBuffer.wrap(e.data)); - - readonly onMessage = Event.filter(this.onRawData, data => data !== 'disconnect') as Event; - readonly onDisconnect = Event.signal(Event.filter(this.onRawData, data => data === 'disconnect')); + readonly onMessage = Event.fromDOMEventEmitter(this.port, 'message', (e: MessageEvent) => VSBuffer.wrap(e.data)); constructor(private port: MessagePort) { // we must call start() to ensure messages are flowing port.start(); - - // when the other end disconnects, ensure that we close - // our end as well to stay in sync - Event.once(this.onDisconnect)(() => port.close()); } send(message: VSBuffer): void { @@ -64,7 +54,6 @@ export class Protocol implements IMessagePassingProtocol { } disconnect(): void { - this.port.postMessage('disconnect'); this.port.close(); } } diff --git a/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts b/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts index 7df6de38d4c876538e85a0ed7b6fdb5df43c7a3b..98e865fe9bf922794477e297c0cc05bd42e05733 100644 --- a/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts +++ b/src/vs/base/parts/ipc/electron-sandbox/ipc.mp.ts @@ -30,7 +30,13 @@ export class Server extends IPCServer { const { port1: incomingPort, port2: outgoingPort } = new MessageChannel(); const protocol = new MessagePortProtocol(incomingPort); - const result: ClientConnectionEvent = { protocol, onDidClientDisconnect: protocol.onDisconnect }; + const result: ClientConnectionEvent = { + protocol, + // Not part of the standard spec, but in Electron we get a `close` event + // when the other side closes. We can use this to detect disconnects + // (https://github.com/electron/electron/blob/11-x-y/docs/api/message-port-main.md#event-close) + onDidClientDisconnect: Event.fromDOMEventEmitter(incomingPort, 'close') + }; // Send one port back to the requestor ipcRenderer.postMessage('vscode:createMessageChannelResult', nonce, [outgoingPort]);