Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/parts/ipc/electron-main/ipc.mp.ts
4780 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { BrowserWindow, IpcMainEvent, MessagePortMain } from 'electron';
7
import { validatedIpcMain } from './ipcMain.js';
8
import { Event } from '../../../common/event.js';
9
import { IDisposable } from '../../../common/lifecycle.js';
10
import { generateUuid } from '../../../common/uuid.js';
11
import { Client as MessagePortClient } from '../common/ipc.mp.js';
12
13
/**
14
* An implementation of a `IPCClient` on top of Electron `MessagePortMain`.
15
*/
16
export class Client extends MessagePortClient implements IDisposable {
17
18
/**
19
* @param clientId a way to uniquely identify this client among
20
* other clients. this is important for routing because every
21
* client can also be a server
22
*/
23
constructor(port: MessagePortMain, clientId: string) {
24
super({
25
addEventListener: (type, listener) => port.addListener(type, listener),
26
removeEventListener: (type, listener) => port.removeListener(type, listener),
27
postMessage: message => port.postMessage(message),
28
start: () => port.start(),
29
close: () => port.close()
30
}, clientId);
31
}
32
}
33
34
/**
35
* This method opens a message channel connection
36
* in the target window. The target window needs
37
* to use the `Server` from `electron-browser/ipc.mp`.
38
*/
39
export async function connect(window: BrowserWindow): Promise<MessagePortMain> {
40
41
// Assert healthy window to talk to
42
if (window.isDestroyed() || window.webContents.isDestroyed()) {
43
throw new Error('ipc.mp#connect: Cannot talk to window because it is closed or destroyed');
44
}
45
46
// Ask to create message channel inside the window
47
// and send over a UUID to correlate the response
48
const nonce = generateUuid();
49
window.webContents.send('vscode:createMessageChannel', nonce);
50
51
// Wait until the window has returned the `MessagePort`
52
// We need to filter by the `nonce` to ensure we listen
53
// to the right response.
54
const onMessageChannelResult = Event.fromNodeEventEmitter<{ nonce: string; port: MessagePortMain }>(validatedIpcMain, 'vscode:createMessageChannelResult', (e: IpcMainEvent, nonce: string) => ({ nonce, port: e.ports[0] }));
55
const { port } = await Event.toPromise(Event.once(Event.filter(onMessageChannelResult, e => e.nonce === nonce)));
56
57
return port;
58
}
59
60