55 lines
4.7 KiB
Markdown
55 lines
4.7 KiB
Markdown
# 代理实现中涉及的几类Channel
|
||
|
||
## 指令通道(CmdChannel)
|
||
- 该channel负责维护客户端与服务端之间的指令通讯,由客户端启动后向服务端发起连接请求,服务端验证license成功后连接建立。
|
||
- 服务端维护第一个CmdChannel的映射表,key为licenseId。服务端可以根据licenseId,向指定的客户端指令通道发布指令。
|
||
- 该通道建立完成后,服务端会将该license授权的外网映射端口打开,等待用户访问。正常情况下,只要客户端不下线,该通道一直可用。
|
||
- 然后服务端维护第二个CmdChannel的映射表,key为服务端外网端口。服务端可以根据指定的外网端口,向指定的客户端指令通道发布指令。
|
||
|
||
## 用户访问通道(VisitorChannel)
|
||
- 该channel负责维护访问者与服务端端口之间的通讯,由访问者向服务端映射的外网端口发起请求开始建立,具体断开时机由实际的被代理的
|
||
协议决定。
|
||
- 如HTTP/1.0下,用户向该端口发起请求,响应结束后,该通道随之关闭,下一次发起请求后,重新建立新的连接。
|
||
- 该连接建立后,服务端会向该外网端口映射的指令通道发送`Connect`指令,传输该外网端口需要代理的内网信息,
|
||
如:`127.0.0.1:3306`。
|
||
|
||
## 被代理服务的实际通道(RealServerChannel)
|
||
- 该channel负责维护客户端与实际被代理服务之间的通讯,当客户端接收到服务端的`Connect`指令后,客户端便会建立该通道。
|
||
|
||
## 代理数据传输的通道(ProxyChannel)
|
||
- 该channel负责完成内网被代理服务与代理服务端之间的数据转发任务。
|
||
- 每个客户端维护一个`ProxyChannel`的缓存队列,需要时从该队列中取,当取不到时,直接新建一个`ProxyChannel`返回。
|
||
当一个`ProxyChannel`实例用完后,需要归还到缓存队列中(`ProxyChannel`收到`DisConnect`指令时)。
|
||
- 当`RealServerChannel`建立完成后,就会获取相关联的`ProxyChannel`,并与其绑定。设置`RealServerChannel`为
|
||
可读状态。然后通过`ProxyChannel`向服务端发送`Connect`指令。
|
||
|
||
|
||
# 代理实现流程
|
||
## 1、服务连接阶段
|
||
- 1.1、客户端根据是否需要使用SSL,选择对应的服务端端口发起连接,建立`CmdChannel`。
|
||
- 1.2、客户端根据用户输入或配置文件获取`license`,并携带`license`通过`CmdChannel`向服务端发送`Auth`指令。
|
||
- 1.3、服务端通过`CmdChannel`接收到来自客户端的`Auth`指令。若验证`license`有效,则建立`licenseId`与`CmdChannel`的映射缓存、
|
||
外网端口与`CmdChannel`的映射缓存。并启动服务端代理端口,等待用户连接。
|
||
## 2、用户连接阶段
|
||
- 2.1、用户向服务端代理的外网端口发起请求,服务端建立`VisitorChannel`。
|
||
- 2.2、根据外网端口查找`CmdChannel`,若不存在有效的`CmdChannel`,则关闭该`VisitorChannel`。否则,
|
||
设置`VisitorChannel`为不可读,并携带内网映射信息(如:`127.0.0.1:3306`)通过`CmdChannel`向客户端发送`Connect`指令。
|
||
## 3、实际被代理服务连接阶段
|
||
- 3.1、客户端通过`CmdChannel`接收到服务端的`Connect`指令。拿到需要代理的内网IP、端口号,向实际被
|
||
代理服务发起连接请求,若连接失败,则通过`CmdChannel`向服务端发送`DisConnect`指令。建立`RealServerChannel`成功,设置`RealServerChannel`为不可读
|
||
状态,并进入4.1阶段
|
||
## 4、代理通道连接阶段
|
||
- 4.1、客户端通过`ProxyChannelQueue`获取或新建一个`ProxyChannel`,并将`RealServerChannel`与`ProxyChannel`进行绑定。
|
||
- 4.2、客户端通过`ProxyChannel`向服务端发送`Connect`指令。
|
||
- 4.3、服务端通过`ProxyChannel`通道收到来自客户端的`Connect`指令后,将`ProxyChannel`与对应的`VisitorChannel`进行绑定,并
|
||
设置`VisitorChannel`为可读状态。
|
||
## 5、数据传输阶段
|
||
- 5.1、服务端通过`VisitorChannel`收到来自用户的请求数据,然后找到`VisitorChannel`绑定的`ProxyChannel`,
|
||
通过`ProxyChannel`发送`Transfer`指令,并携带用户请求数据。
|
||
- 5.2、客户端通过`ProxyChannel`收到来自服务端的`Transfer`指令,取出用户请求数据。找到`ProxyChannel`绑定的`RealServerChannel`,
|
||
通过`RealServerChannel`向被代理服务写入用户请求数据。
|
||
- 5.3、客户端通过`RealServerChannel`收到被代理服务响应的数据,找到`RealServerChannel`绑定的`ProxyChannel`,
|
||
通过`ProxyChannel`向服务端发送`Transfer`指令,并携带响应数据。
|
||
- 5.4、服务端通过`ProxyChannel`收到来自客户端的`Transfer`指令,找到`ProxyChannel`绑定的`VisitorChannel`,
|
||
通过`VisitorChannel`向用户端写入响应数据。
|