vscode源码分析【七】主进程启动消息通信服务
第一篇: vscode源码分析【一】从源码运行vscode
第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第四篇:vscode源码分析【四】程序启动的逻辑,最初创建的服务
第五篇:vscode源码分析【五】事件分发机制
第六篇:vscode源码分析【六】服务实例化和单例的实现
在mian.ts中的doStartup方法里,创建了一个命名管道服务
(src\vs\code\electron-main\main.ts)
server = await serve(environmentService.mainIPCHandle);
once(lifecycleService.onWillShutdown)(() => server.dispose());
传入的environmentService.mainIPCHandle是命名管道的识别路径,
一个有规则的字符串,规则如下:
function getWin32IPCHandle(userDataPath: string, type: string): string {
const scope = crypto.createHash('md5').update(userDataPath).digest('hex');
return `\\\\.\\pipe\\${scope}-${pkg.version}-${type}-sock`;
}
注意:每次启动程序,取这个字符串的时候,都会获得同样的值(而且这个值是会被缓存起来的);
以后监听消息、发送消息,都根据这个字符串来;
创建服务的代码(serve):
export function serve(hook: any): Promise<Server> {
return new Promise<Server>((c, e) => {
const server = createServer();
server.on('error', e);
server.listen(hook, () => {
server.removeListener('error', e);
c(new Server(server));
});
});
}
这个方法返回了一个Promise的对象,
c和e是Promise的参数,c代表成功时的回调,e代表失败时的回调(有点类似es6的Promise)
匿名函数内createServer就是nodejs里的原生接口,
Server类绑定了连接和断开的事件,暂时不细说;
回头看看main.ts startup方法里有这么一句:
instantiationService.createInstance(CodeApplication, mainIpcServer, instanceEnvironment).startup();
这句显然是创建了CodeApplication的实例,然后执行了实例的startup方法
注意:创建这个实例的时候,把我们前面创建的mainIpcServer传递进去了;
CodeApplication(src\vs\code\electron-main\app.ts)的startup方法,还启动了Electron的IPCServer
const electronIpcServer = new ElectronIPCServer();
vscode把electron默认的通信机制也接入到了自己的事件体系内,有消息过来,会触发事件;
具体先不细说,后面再讲.
接着就跳转到同类型里的openFirstWindow方法(是不是很熟悉,我们在第一篇文章中讲到过这里)
在这里,给这两个服务(mainIpcServer和electronIpcServer ),创建了一堆信道:
const launchService = accessor.get(ILaunchService);
const launchChannel = new LaunchChannel(launchService);
this.mainIpcServer.registerChannel('launch', launchChannel);
const updateService = accessor.get(IUpdateService);
const updateChannel = new UpdateChannel(updateService);
electronIpcServer.registerChannel('update', updateChannel);
const issueService = accessor.get(IIssueService);
const issueChannel = new IssueChannel(issueService);
electronIpcServer.registerChannel('issue', issueChannel);
const workspacesService = accessor.get(IWorkspacesMainService);
const workspacesChannel = new WorkspacesChannel(workspacesService);
electronIpcServer.registerChannel('workspaces', workspacesChannel);
const windowsService = accessor.get(IWindowsService);
const windowsChannel = new WindowsChannel(windowsService);
electronIpcServer.registerChannel('windows', windowsChannel);
sharedProcessClient.then(client => client.registerChannel('windows', windowsChannel));
const menubarService = accessor.get(IMenubarService);
const menubarChannel = new MenubarChannel(menubarService);
electronIpcServer.registerChannel('menubar', menubarChannel);
const urlService = accessor.get(IURLService);
const urlChannel = new URLServiceChannel(urlService);
electronIpcServer.registerChannel('url', urlChannel);
const storageMainService = accessor.get(IStorageMainService);
const storageChannel = this._register(new GlobalStorageDatabaseChannel(this.logService, storageMainService as StorageMainService));
electronIpcServer.registerChannel('storage', storageChannel);
const logLevelChannel = new LogLevelSetterChannel(accessor.get(ILogService));
electronIpcServer.registerChannel('loglevel', logLevelChannel);
有存储、日志、菜单栏、工作台、升级.....等等
主要的通信还是用electronIpcServer 来干的,mainIpcServer只有一个launch信道;
下面我们看看消息是怎么传递的
我们随便打开一个信道的类型(src\vs\platform\windows\node\windowsIpc.ts)
它有两个主要的函数,listen和call,
listen(_: unknown, event: string): Event<any> {
switch (event) {
case 'onWindowOpen': return this.onWindowOpen;
case 'onWindowFocus': return this.onWindowFocus;
case 'onWindowBlur': return this.onWindowBlur;
case 'onWindowMaximize': return this.onWindowMaximize;
case 'onWindowUnmaximize': return this.onWindowUnmaximize;
case 'onRecentlyOpenedChange': return this.onRecentlyOpenedChange;
}
throw new Error(`Event not found: ${event}`);
}
call(_: unknown, command: string, arg?: any): Promise<any> {
switch (command) {
case 'pickFileFolderAndOpen': return this.service.pickFileFolderAndOpen(arg);
case 'pickFileAndOpen': return this.service.pickFileAndOpen(arg);
case 'pickFolderAndOpen': return this.service.pickFolderAndOpen(arg);
case 'pickWorkspaceAndOpen': return this.service.pickWorkspaceAndOpen(arg);
case 'showMessageBox': return this.service.showMessageBox(arg[0], arg[1]);
case 'showSaveDialog': return this.service.showSaveDialog(arg[0], arg[1]);
case 'showOpenDialog': return this.service.showOpenDialog(arg[0], arg[1]);
//......
消息来了,进入listen函数,发送消息,进入call函数;
注意,消息来了,触发的也不是他自己的方法,我们看看它的构造函数:
constructor(private service: IWindowsService) {
this.onWindowOpen = Event.buffer(service.onWindowOpen, true);
this.onWindowFocus = Event.buffer(service.onWindowFocus, true);
this.onWindowBlur = Event.buffer(service.onWindowBlur, true);
this.onWindowMaximize = Event.buffer(service.onWindowMaximize, true);
this.onWindowUnmaximize = Event.buffer(service.onWindowUnmaximize, true);
this.onRecentlyOpenedChange = Event.buffer(service.onRecentlyOpenedChange, true);
}
看到没,触发的其实是一个事件,事件是关联到service实例的;
这个实例是这样创建的:
const windowsService = accessor.get(IWindowsService);
具体的代码在:src\vs\platform\windows\electron-browser\windowsService.ts
vscode源码分析【七】主进程启动消息通信服务的更多相关文章
- vscode源码分析【九】窗口里的主要元素
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【八】加载第一个画面
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...
- vscode源码分析【四】程序启动的逻辑,最初创建的服务
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- v76.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式 | 百篇博客分析OpenHarmony源码
百篇博客分析|本篇为:(共享内存篇) | 进程间最快通讯方式 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) | 同样 ...
- SpringBoot源码分析之SpringBoot的启动过程
SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30 | 分类于 springboot | 0 Comments | 阅读次数 SpringB ...
- vscode源码分析【六】服务实例化和单例的实现
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【五】事件分发机制
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- 鸿蒙内核源码分析(内存主奴篇) | 皇上和奴才如何相处 | 百篇博客分析OpenHarmony源码 | v10.04
百篇博客系列篇.本篇为: v10.xx 鸿蒙内核源码分析(内存主奴篇) | 皇上和奴才如何相处 | 51.c.h .o 前因后果相关篇为: v08.xx 鸿蒙内核源码分析(总目录) | 百万汉字注解 ...
随机推荐
- 轻松定位CPU飙高问题
以下四步轻松定位CPU飙高问题: ①top pid 查看cpu耗CPU进程 ②top -Hp pid 查看该进程所有线程的运行情况,找到占用 CPU 过高的线程 pid ③ printf %x pid ...
- python检查字典元素是否存在类似php中isset()方法
PHP中isset()方法来检查数组元素是否存在,在Python中无对应函数,在Python中一般可以通过异常来处理数组元素不存在的情况,而无须事先检查 Python的编程理念是“包容错误”而不是“严 ...
- Registering current configuration as safe fallback point
14:28:23,255 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList@f5f2bb7 - URL [jar:file: ...
- qq cookie
qq cookie from selenium import webdriver from selenium.webdriver import ActionChains import time, re ...
- Fiddler之模拟响应、修改请求或响应数据(断点)
在测试过程中,有时候需要修改请求或响应数据,或者直接模拟服务器响应,此时可以使用fiddler进行此类操作.可以使用断点功能完成. 一.修改请求数据 在发起请求后,需要修改请求的数据时,可以设置请求前 ...
- 推荐系统| ② 离线推荐&基于隐语义模型的协同过滤推荐
一.离线推荐服务 离线推荐服务是综合用户所有的历史数据,利用设定的离线统计算法和离线推荐算法周期性的进行结果统计与保存,计算的结果在一定时间周期内是固定不变的,变更的频率取决于算法调度的频率. 离线推 ...
- SQl Server 中的decimal( m , n )的意思
create table sc( cno ), sno ), grade ,), primary key(cno,sno), foreign key(cno) references cou(cno), ...
- Hive 报错 Error while compiling statement: FAILED: ParseException line 1:0 character '' not supported here (state=42000,code=40000)
Hive报错 Error while compiling statement: FAILED: ParseException line 1:0 character '' not supported h ...
- 【朝花夕拾】Android自定义View篇之(七)Android事件分发机制(下)滑动冲突解决方案总结
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/11072989.html],谢谢! 前面两篇文章,花了很大篇幅讲解了Android的事件分发机制 ...
- React 从入门到进阶之路(二)
在之前的文章中我们介绍了 React 开发的环境搭建及目录介绍和整理,本篇文章将介绍 React 创建组件.JSX 语法.绑定数据和绑定对象. 之前我们已经将项目运行了起来,我们再来看一下目录结构: ...