在上一篇中,我们一起分析了 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 模块的基本架构,了解了进程间的通信细节。

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

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

参考

VSCode 的官方文档

VSCode API

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

vscode 源码解析 - 进程间调用

VS Code For Web 深入浅出 -- 进程间通信篇的更多相关文章

  1. VS Code For Web 深入浅出 -- 导读篇

    下一代 IDE 的形态究竟是什么呢?VS Code For Web 试图回答这个问题. 背景 众所周知,VS Code 是当前工业界最优秀的代码编辑器之一.它由<设计模式>的作者 Eric ...

  2. 我所理解的RESTful Web API [设计篇]

    <我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...

  3. Web 播放声音 — Flash 篇 (播放 AMR、WAV)

    本文主要介绍 Flash 播放 AMR 格式 Base64码 音频. 在此之前么有接触过 Flash ,接触 AS3 是一头雾水,不过幸好有 TypeScript 和 JavaScript 的基础看起 ...

  4. Spring Boot干货系列:(五)开发Web应用JSP篇

    Spring Boot干货系列:(五)开发Web应用JSP篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 上一篇介绍了Spring Boot中使用Thymeleaf模板引擎,今天 ...

  5. 【一套代码小程序&Native&Web阶段总结篇】可以这样阅读Vue源码

    前言 前面我们对微信小程序进行了研究:[微信小程序项目实践总结]30分钟从陌生到熟悉 在实际代码过程中我们发现,我们可能又要做H5站又要做小程序同时还要做个APP,这里会造成很大的资源浪费,如果设定一 ...

  6. Sample Code之Web scene-slides

    这是我的第一篇随笔,在开始正文前说几句. 这个系列会记录我学习Arcgis js API 4.10的全过程,希望能对自己也对其他有需要的人有帮助.很多时候上网看一些大神的帖子会感到一头雾水,一是自己水 ...

  7. 实现手机扫描二维码页面登录,类似web微信-第二篇,关于二维码的自动生成

    转自:http://www.cnblogs.com/fengyun99/p/3541251.html 接上一章,我们已经基本把业务逻辑分析清楚了 下面我们第一步,实现二维码的web动态生成. 页面的二 ...

  8. 实现手机扫描二维码页面登录,类似web微信-第一篇,业务分析

    转自:http://www.cnblogs.com/fengyun99/p/3541249.html 关于XMPP组件的文章,先休息两天,好歹已经完整的写了一份. 这两天,先实现一套关于web微信扫描 ...

  9. 走进科学之WAF(Web Appllication Firewall)篇

    小编P.S:文章非常详尽对WAF领域进行了一次科普,能有让人快速了解当前WAF领域的相关背景及现状,推荐所有WAF领域的同学阅读本文. 1. 前言 当WEB应用越来越为丰富的同时,WEB 服务器以其强 ...

随机推荐

  1. Quicker程序实用及获取

    -- 仅代表个人见解 --官方网站:https://getquicker.net/主界面截图   桌面图标截图   3分钟快速体验Quicker  https://getquicker.net/KC/ ...

  2. Java开发学习(二十二)----Spring事务属性、事务传播行为

    一.事务配置 上面这些属性都可以在@Transactional注解的参数上进行设置. readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true. timeout ...

  3. Python带我起飞——入门、进阶、商业实战_ 入门版电子书籍分享,

    Python带我起飞--入门.进阶.商业实战_ 免费下载地址 内容简介 · · · · · · <Python带我起飞--入门.进阶.商业实战>针对Python 3.5 以上版本,采用&q ...

  4. Luogu P5030 长脖子鹿放置(网络流)

    匈牙利T了,Dinic飞了... 按奇偶连 #include <cstdio> #include <iostream> #include <cstring> #in ...

  5. 从C过渡到C++(1)——GNU/Linux

    从C过渡到C++(1)--GNU/Linux 目录 从C过渡到C++(1)--GNU/Linux 大名鼎鼎的GNU/Linux GNU GNU的组成 一点补充 MinGW 运行时库 额外的内容 Min ...

  6. 不想当Window的Dialog不是一个好Modal,弹窗翻身记

    弹窗是我们熟视无睹的一种交互方式,经常用到,但从没好好想过这种交互行为背后的意义... 弹窗是Windows的灵魂 Windows的灵魂是什么?当然是Window,当方便快捷的多窗口进入人们视野的时候 ...

  7. Jetpack架构组件学习(4)——APP Startup库的使用

    最近在研究APP的启动优化,也是发现了Jetpack中的App Startup库,可以进行SDK的初始化操作,于是便是学习了,特此记录 原文:Jetpack架构组件学习(4)--App Startup ...

  8. noip 2014 提高组初赛

    noip 2014 提高组初赛 一. TCP协议属于哪一层协议( ) A. 应用层 B. 传输层 C. 网络层 D. 数据链路层 B TCP(传输控制协议) 若有变量int a; float: x, ...

  9. KingbaseES 与Oracle 函数稳定性对于性能影响差异比较

    一.函数的属性 KingbaseES 函数在定义时有三种稳定性级别:volatile.stable 和 immutable.默认情况下,创建函数的稳定性为volatile.以下是这三种函数的区别: V ...

  10. Spring Boot 整合Hibernate Validator

    Spring Boot 整合Hibernate Validator 依赖 <dependencies> <dependency> <groupId>org.spri ...