本文介绍 VSCode 中的 ChannelServer 和 ChannelClient。
前面提到,VSCode 中 Server 对象维护了一个 Channel 的列表,客户端连接 Server 时可以会创建一个连接 Connection,Connection 中的 channelClient 可以发起请求调用方法或监听事件,请求打包成一条消息发送给 channelServer,channelServer 负责和 Server 的 Channel 交互得到响应的结果,再通过消息将结果返回给 channelClient。本文主要介绍 channelClient 和 channelServer 之间的通讯细节。
1 | call / listen call / listen |
channelClient 进行 call 和 listen
调用 channelClient 的 getChannel 方法可以得到一个可以调用 channelServer 中的 Channel 的本地 Channel ( 或者说客户端 Channel )。调用该 Channel 的 call 方法,会调用 channelServer 中对应的 Channel 的 call 方法 ( 向 ChannelServer 发起请求 ),channelServer 中对应的 Channel 的 call 执行后会将结果返回给本地 Channel,最终由本地 Channel 返回包含调用结果的 Promise。
事件处理类似,调用本地 Channel 的 listen 方法,会得到一个本地的监听器,当 channelServer 中对应的事件触发时,会触发该监听器并带上响应的数据。
1 | class ChannelClient { |
发起 call 请求
发起 call 请求使用 requestPromise 实现。requestPromise 先为本次请求计算一个请求 ID,然后为本次请求注册一个 handler ( 和 ID 相关联 ),当 channelServer 返回结果时,会触发 protocol 的 onMessage ( 此时会调用 onBuffer 方法,该方法又会调用 onResponse 方法),此时根据请求 ID 调用对应的 handler,最终 handler 将结果包裹在 Promise 中返回。
1 | private requestPromise(channelName: string, name: string, arg?: any, cancellationToken = CancellationToken.None): Promise<any> { |
发起 listen 请求
listen 原理和 call 类似:
1 | private requestEvent(channelName: string, name: string, arg?: any): Event<any> { |
channelServer 处理 call 和 listen 请求
channelServer 处理 call 和 listen 请求从得到请求开始,channelServer 通过 protocol 的 onMessage 事件得到请求,并使用 onRawMessage 对不同类型的消息进行处理 ( 使用 onPromise 处理函数调用请求,使用 onEventListen 处理事件监听请求 )。
处理 call 请求
onPromise 首先从 Channel 列表中取出请求的 Channel,如果有相应的 Channel 直接调用相应的 call 方法。得到的结果使用 sendResponse 直接发给客户端:
1 | private onPromise(request: IRawPromiseRequest): void { |
处理 listen 请求
过程与 call 类似,当事件触发时,向客户端发送事件触发消息,并带上相应的数据:
1 | private onEventListen(request: IRawEventListenRequest): void { |
小结
总的来说,channelServer 负责维护一组 Channel,接收请求调用 Channel 并响应相应的结果。channelClient 则对外提供 getChannel 接口,用于取得一个可以调用 channelServer 上的指定 Channel 的 Channel,用户直接调用这个 Channel 的方法 ( call 和 listen ) 相当于直接调用对应的 channelServer 上的 Channel。总结如图:
1 | call / listen call / listen |