In the previous article, we analyzed the overall code structure of VS Code and learned that VS Code is developed by separating the front and back ends. And no matter whether the front end is based on electron or web, and the back end is local or cloud, the calling method is the same.
Under such an architecture, how is the communication method between the front and back ends realized? In this article, we will explore the inter-process communication method of VS Code For Web.
Process communication and calling method
IPC
For projects with a multi-process architecture, the communication between processes will be through Inter Process Calling (IPC). VSCode has designed a special IPC module to realize communication. The code is located in src/vs/base/parts/ipc .
export const enum RequestType {
Promise = 100,
PromiseCancel = 101,
EventListen = 102,
EventDispose = 103
}
As can be seen from the enum type, VSCode's IPC module supports two calling methods at the same time, one is based on Promise calling implementation, and the other is implemented through the event monitoring mechanism of Event Emitter/Listener.
vscode-jsonrpc
Taking the event monitoring mechanism as an example, this package is used in VSCode to encapsulate the implementation, and the calling method is as follows:
import * as cp from 'child_process';
import * as rpc from 'vscode-jsonrpc/node';
let childProcess = cp.spawn(...);
// Use stdin and stdout for communication:
let connection = rpc.createMessageConnection(
new rpc.StreamMessageReader(childProcess.stdout),
new rpc.StreamMessageWriter(childProcess.stdin));
let notification = new rpc.NotificationType<string, void>('testNotification');
connection.listen();
connection.sendNotification(notification, 'Hello World');
Server calls are also wrapped similarly:
import * as rpc from 'vscode-jsonrpc/node';
let connection = rpc.createMessageConnection(
new rpc.StreamMessageReader(process.stdin),
new rpc.StreamMessageWriter(process.stdout));
let notification = new rpc.NotificationType<string, void>('testNotification');
connection.onNotification(notification, (param: string) => {
console.log(param); // This prints Hello World
});
connection.listen();
interprocess communication unit
In order to realize the point-to-point communication between the client and the server, we need a minimum unit to realize the invocation and monitoring of messages. In VSCode, this smallest unit is Channel
.
/**
* An `IChannel` is an abstraction over a collection of commands.
* You can `call` several commands on a channel, each taking at
* most one single argument. A `call` always returns a promise
* with at most one single return value.
*/
export interface IChannel {
call<T>(command: string, arg?: any, cancellationToken?: CancellationToken): Promise<T>;
listen<T>(event: string, arg?: any): Event<T>;
}
Each communication process requires the client and server to be in the same server Channel
.
inter-process communication
In VSCode, the communication between the client and the server is established through classes, and the connection is instantiated Connection
by passing in the client and the server Channel
, that is, ChannelClient
and .ChannelServer
interface Connection<TContext> extends Client<TContext> {
readonly channelServer: ChannelServer<TContext>;
readonly channelClient: ChannelClient;
}
The difference between them is that since the server can serve multiple clients at the same time, it supports multiple Channel
acquisitions, but ChannelClient
it is a one-to-one connection.
In summary, we have sorted out the basic structure of the IPC module in VSCode, and understood the communication details between processes.
Use a picture to summarize and sort out the knowledge points:
Since VSCode's IPC module naturally supports asynchronous capabilities, it does not actually distinguish whether a process is a local process or a remote process. As long as it communicates, Channel
it can be considered as inter-process communication, and the same code can be reused.
reference
Official documentation of VSCode
Interpretation of VSCode source code--IPC communication mechanism
Vscode source code analysis - inter-process call