本文介绍 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 |