ToB企服应用市场:ToB评测及商务社交产业平台

标题: 41. 干货系列从零用Rust编写负载均衡及代理,websocket与tcp的映射,WS与TC [打印本页]

作者: 愛在花開的季節    时间: 2024-4-5 18:41
标题: 41. 干货系列从零用Rust编写负载均衡及代理,websocket与tcp的映射,WS与TC
wmproxy

wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代理等,会将实现过程分享出来,感兴趣的可以一起造个轮子
项目地址

国内: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
项目设计目标

针对有一些应用场景需要将TCP转成websocket的,就比如旧的客户端或者旧的服务端比较不合适进行改造,但是又需要借助阿里的全站加速DCDN等这类服务或者其它可能需要特定浏览器协议的情况下,需要进行协议的转化而服务。
Tcp转Websocket

流程图

以下展示Tcp转Websocket的流程图,就纯粹的Tcp客户端在不经过任何源码修改的情况下成功连接websocket服务端
flowchart TD    A[tcp客户端] -->|连接服务| B[服务节点]    B -->|服务转化| C[websocket客户端]    C -->|连接服务| D[websocket服务端]比较适合原生客户端,又不想引入第三方库,又能在需要的时候直接使用websocket来做配合。
源码实现

实现源码在stream_to_ws
  1. /// 将tcp的流量转化成websocket的流量
  2. pub struct StreamToWs<T: AsyncRead + AsyncWrite + Unpin> {
  3.     url: Url,
  4.     io: T,
  5. }
复制代码
定义回调类:
  1. struct Operate {
  2.     /// 将tcp来的数据流转发到websocket
  3.     stream_sender: Sender<Vec<u8>>,
  4.     /// 从websocket那接收信息
  5.     receiver: Option<Receiver<OwnedMessage>>,
  6. }
复制代码
核心转发逻辑:
  1. pub async fn copy_bidirectional(self) -> ProtResult<()> {
  2.     let (ws_sender, ws_receiver) = channel::<OwnedMessage>(10);
  3.     let (stream_sender, stream_receiver) = channel::<Vec<u8>>(10);
  4.     let url = self.url;
  5.     tokio::spawn(async move {
  6.         if let Ok(mut client) = Client::builder().url(url).unwrap().connect().await {
  7.             client.set_callback_ws(Box::new(Operate {
  8.                 stream_sender,
  9.                 receiver: Some(ws_receiver),
  10.             }));
  11.             let _e = client.wait_ws_operate().await;
  12.         }
  13.     });
  14.     Self::bind(self.io, ws_sender, stream_receiver).await?;
  15.     Ok(())
  16. }
复制代码
创建两对发送接收对分别为OwnedMessage及Vec来进行双向绑定,并在协程中发起对websocket的连接请求。更多的逻辑请查看源码。
测试demo

示例文件ws_stw,当下监听8082的流量并将其转发到8081的websocket服务上,测试借助websocat做测试服务端
成功测试转发
Websocket转Tcp

流程图

以下展示Websocket转Tcp的流程图,通常由浏览器环境中发起(因为浏览器的标准全双工就是websocket)。然后服务器这边由TCP的方案
flowchart TD    A[websocket客户端] -->|连接服务| B[服务节点]    B -->|服务转化| C[tcp客户端]    C -->|连接服务| D[tcp服务端]比较适合原生服务端,又不想引入第三方库,又能兼容TCP及websocket协议,适合在这个做个中间层。
源码实现

实现源码在ws_to_stream
  1. /// 将websocket的流量转化成的tcp流量
  2. pub struct WsToStream<T: AsyncRead + AsyncWrite + Unpin + Send + 'static, A: ToSocketAddrs> {
  3.     addr: A,
  4.     io: T,
  5. }
复制代码
与tcp转websocket类似,但是此时是将io流量转成Server的处理函数。
测试demo

示例文件ws_wts,当下监听8082的流量并将其转发到8081的websocket服务上,测试借助websocat做测试服务端
新建测试TCP的监听,原样转发的测试代码:
  1. struct Operate {
  2.     /// 将tcp来的数据流转发到websocket
  3.     stream_sender: Sender<Vec<u8>>,
  4.     /// 从websocket那接收信息
  5.     receiver: Option<Receiver<OwnedMessage>>,
  6. }
复制代码

成功测试转发
组合方案

当我们现存的网络方案为Tcp到Tcp或者为Websocket到Websocket而我们在中间的传输过程中如想利用DCDN做源地址保护,而他只支持Websocket,此时我们就可以利用数据的转化,将我们的数据包通过DCDN做转发:
flowchart TD    A[TCP客户端] -->|连接服务| B[服务节点]    B -->|转化成websocket通过加速| C[DCDN全站加速]    C -->|连接服务| E[服务节点]    E -->|转化成Tcp并串连到服务端| F[TCP服务端]这样子我们就可以利用基础网络中的CDN或者DCDN等服务,又不用对旧的数据进行修改或者无法修改的程序就比如远程服务通过CDN进行加速等。
小结

协议的自由转化可以帮助我们创建更合适的网络环境,可以让运维更自由的构建系统。利用转化可以用好全站加速DCDN这类的功能,可以更好的保护源站,防止被DDOS攻击。
点击 [关注][在看][点赞] 是对作者最大的支持

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4