Path: blob/main/src/vs/base/parts/ipc/electron-main/ipc.mp.ts
4780 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { BrowserWindow, IpcMainEvent, MessagePortMain } from 'electron';6import { validatedIpcMain } from './ipcMain.js';7import { Event } from '../../../common/event.js';8import { IDisposable } from '../../../common/lifecycle.js';9import { generateUuid } from '../../../common/uuid.js';10import { Client as MessagePortClient } from '../common/ipc.mp.js';1112/**13* An implementation of a `IPCClient` on top of Electron `MessagePortMain`.14*/15export class Client extends MessagePortClient implements IDisposable {1617/**18* @param clientId a way to uniquely identify this client among19* other clients. this is important for routing because every20* client can also be a server21*/22constructor(port: MessagePortMain, clientId: string) {23super({24addEventListener: (type, listener) => port.addListener(type, listener),25removeEventListener: (type, listener) => port.removeListener(type, listener),26postMessage: message => port.postMessage(message),27start: () => port.start(),28close: () => port.close()29}, clientId);30}31}3233/**34* This method opens a message channel connection35* in the target window. The target window needs36* to use the `Server` from `electron-browser/ipc.mp`.37*/38export async function connect(window: BrowserWindow): Promise<MessagePortMain> {3940// Assert healthy window to talk to41if (window.isDestroyed() || window.webContents.isDestroyed()) {42throw new Error('ipc.mp#connect: Cannot talk to window because it is closed or destroyed');43}4445// Ask to create message channel inside the window46// and send over a UUID to correlate the response47const nonce = generateUuid();48window.webContents.send('vscode:createMessageChannel', nonce);4950// Wait until the window has returned the `MessagePort`51// We need to filter by the `nonce` to ensure we listen52// to the right response.53const onMessageChannelResult = Event.fromNodeEventEmitter<{ nonce: string; port: MessagePortMain }>(validatedIpcMain, 'vscode:createMessageChannelResult', (e: IpcMainEvent, nonce: string) => ({ nonce, port: e.ports[0] }));54const { port } = await Event.toPromise(Event.once(Event.filter(onMessageChannelResult, e => e.nonce === nonce)));5556return port;57}585960