实现原理
# 代理实现中涉及的几类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
向用户端写入响应数据。
上次更新: 2023/10/26, 13:41:02