首页 > 系统相关 >VS Code For Web 深入浅出 -- 进程间通信篇

VS Code For Web 深入浅出 -- 进程间通信篇

时间:2022-10-20 11:50:42浏览次数:66  
标签:Web Code VSCode 间通信 rpc 调用 进程 new

在上一篇中,我们一起分析了 VS Code 整体的代码架构,了解了 VS Code 是由前后端分离的方式开发的。且无论前端是基于 electron 还是 web,后端是本地还是云端,其调用方式并无不同。

这样的架构下,前后端的通信方式是如何实现的呢?本篇我们将一起来探究 VS Code For Web 的进程间通信方式。

进程通信与调用方式

进程间通信协议

对于多进程架构的项目,进程之间的通信会通过进程间调用 (Inter Process Calling, IPC)。VSCode 中自己设计了专门的 IPC 模块来实现通信。代码位于 src/vs/base/parts/ipc

export const enum RequestType {
    Promise = 100,
    PromiseCancel = 101,
    EventListen = 102,
    EventDispose = 103
}

从 enum type 可以看出,VSCode 的 IPC 模块同时支持两种调用方式,一种是基于 Promise 的调用实现, 另一种是通过 Event Emitter/Listener 的那一套事件监听机制来实现。

以事件监听机制为例,VSCode 中采用 vscode-jsonrpc 这个包来封装实现,调用方式如下:

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');

服务端调用也采用类似的包装:

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();

进程间通信单元

为了实现客户端与服务端之间的点对点通信,我们需要一个最小单元来实现消息的调用与监听。在 VSCode 中,这个最小单元即为 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>;
}

每次通信过程,需要客户端与服务端处于同一个 Channel 中。

进程间通信建连

在 VSCode 中,客户端与服务端之间的通信建立是通过 Connection 类来建立,通过传入客户端与服务端的 Channel ,即 ChannelClientChannelServer 来实例化连接。

interface Connection<TContext> extends Client<TContext> {
    readonly channelServer: ChannelServer<TContext>;
    readonly channelClient: ChannelClient;
}

它们之间的区别是,由于服务端可以同时对多个客户端服务,因此支持多个 Channel 的获取,而ChannelClient 为一对一连接。

综上,我们就梳理清楚了 VSCode 中 IPC 模块的基本架构,了解了进程间的通信细节。

用一张图总结梳理一下知识点:

20221010150243

由于 VSCode 的 IPC 模块天然支持异步能力,因此事实上它并不区分进程是本地进程还是远端进程,只要是通过 Channel 通信的,都可以被认为是进程间通信,都可以复用相同的代码编写。

参考

VSCode 的官方文档

VSCode API

VSCode 源码解读--IPC 通信机制

vscode 源码解析 - 进程间调用

标签:Web,Code,VSCode,间通信,rpc,调用,进程,new
From: https://www.cnblogs.com/zakum/p/16809239.html

相关文章

  • 什么是web3?
    啥是Web3?能带来什么?要理解Web3,可能还要把Web1和Web2拎出来做个比较。Web1诞生于20世纪90年代,彼时互联网刚刚普及,信息的传播方式是单向的、被动式的。比如,浏览新浪、......
  • Codeforces Round #202 (Div. 1) A. Mafia 推公式 + 二分答案
    ​​http://codeforces.com/problemset/problem/348/A​​A.MafiatimelimitpertestmemorylimitpertestinputoutputOnedaynfriendsgatheredtogethertoplay"Ma......
  • leetcode 197. Rising Temperature sql_Date用法
    ​​https://leetcode.com/problems/rising-temperature/description/​​题目需要选出今天比昨天气温高的ID用join,默认是inner join需要左右两边同时有才行。然后就是用on......
  • Gartner web3 的未来市场前景
    内行人叫web3外行人叫元宇宙元宇宙(Metaverse)Gartner将元宇宙定义为一个由通过虚拟技术增强的物理和数字现实融合而成的集体虚拟共享空间。这个空间具有持久性,能够提供增......
  • LeetCode 关于树的层次遍历一般方法
    思路建立一个队列放入根节点大循环开始,若队列为空则终止函数循环开始,按当前队列长度为终止条件pop取出队头节点若其儿子节点非空,则放入队列循环结束,此时完成一层的......
  • php 调用c# .NET 写的webservice(亲测通过)
    先上结果图——C# 代码:usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Web;usingSystem.Web.Services;usingSystem.Web.Services......
  • leetcode 最长回文子串
    constcountSubstrings=(s)=>{conststrLen=s.length;letnumOfPalindromicStr=0;//初始化一个二维数组letdp=Array.from(Array(strLen),()=>A......
  • WEB-INF/web.xml泄露
    打开题目之后利用弱密码爆破admin/admin888但是很明显这个不是方法之后试试sql注入,无果然后寻找页面其他的点点击help出现这个页面可以看到有个help.docx文件,想......
  • 力扣leetcode 第2394题 求工作时间不达标的员工
    力扣leetcode第2394题求工作时间不达标的员工selectemployee_idfrom(selectDISTINCTe.employee_id,e.needed_hours*60asneeded_hours,ifnull((selectsum(......
  • Go语言的Vscode快捷键
    GO语言快捷键pkgm--快速搭建主函数和导入main包packagemainfuncmain(){}ff--格式化输出fmt.Printf("",var)fp--换行输出fmt.......