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

标题: 24. 从零用Rust编写正反向代理,细说HTTP行为中的几种定时器 [打印本页]

作者: 何小豆儿在此    时间: 2023-12-9 17:08
标题: 24. 从零用Rust编写正反向代理,细说HTTP行为中的几种定时器
wmproxy

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

国内: https://gitee.com/tickbh/wmproxy
github: https://github.com/tickbh/wmproxy
敏感的时间

  现实生活中大家都对时间有着概念,比如“快上班了,要不然要迟到了。”、“这班怎么这么久,怎么还没下班?”、“啊?已经晚上12点啦,等我这把游戏玩完。”、“叮叮叮,起床闹钟一直在催着你起床了。”
  闹钟、自然变化、生物钟为我们提供着时间的保证。而计算机的世界里,就靠着硬件定时器,控制着时间的流逝,如果哪一天本地时间和别人的时间不一致了,此时需要找别人对时,这也就是经典的网络时间协议(NTP)。
  现实的生活中,通常以分钟或者小时乃至天去和别人约定时间,而在计算机的世界里,在我们看来那就是朝生暮死的蚍蜉一般,他们生命较短,所以对他们来说,通常用s或者ms来乃至μs做通知,所以需要严格的遵守时间约定,绝对不允许有赖床的行为。
HTTP行为中的定时器

HTTP/HTTPS/WebSocket的访问撑起了互联网总流量的半臂江山,日常接触中APP或者游戏这种对外服务的基本上均是通过HTTP及HTTPS进行服务,长链接由于兼容小程序这类的大部分游戏直接也从普通的Socket转为WebSocket直接做全网的兼容。WebSocket的基础协议是由HTTP升级而来,所以也归于HTTP协议。
主要有以下列行为定时器
定时器类的定义

相关的超时数据均存放在该类里,接下来类型进行相应的处理
  1. #[derive(Debug)]
  2. pub struct TimeoutLayer {
  3.     pub connect_timeout: Option<Duration>,
  4.     pub read_timeout: Option<Duration>,
  5.     pub write_timeout: Option<Duration>,
  6.     pub timeout: Option<Duration>,
  7.     /// keep alive 超时时长
  8.     pub ka_timeout: Option<Duration>,
  9.     read_timeout_sleep: Option<Pin<Box<Sleep>>>,
  10.     write_timeout_sleep: Option<Pin<Box<Sleep>>>,
  11.     timeout_sleep: Option<Pin<Box<Sleep>>>,
  12.     ka_timeout_sleep: Option<Pin<Box<Sleep>>>,
  13. }
复制代码
连接超时定时器

  此时约定的是客户端向服务端请求TCP连接建立的最长时间,如果没有约定,将由系统连接超时的或者确认不可达的时候才返回失败。
  如果没有连接超时,那么以下我们的型业务场景模拟:
在设计模型中,连接超时必不可少,因为各种业务场景的不同,需要要不同的时间内得到预期的反馈。以下是连接超时在Rust中的实现,因为只存在于客户端主动连接服务端,所以连接超时只在客户端实现。
  1. async fn inner_connect<A: ToSocketAddrs>(&self, addr: A) -> ProtResult<TcpStream> {
  2.     if self.inner.timeout.is_some() {
  3.         // 获取是否配置了连接超时, 如果有连接超时那么指定timeout
  4.         if let Some(connect) = &self.inner.timeout.as_ref().unwrap().connect_timeout {
  5.             match tokio::time::timeout(*connect, TcpStream::connect(addr)).await {
  6.                 Ok(v) => {
  7.                     return Ok(v?)
  8.                 }
  9.                 Err(_) => return Err(ProtError::Extension("connect timeout")),
  10.             }
  11.         }
  12.     }
  13.     let tcp = TcpStream::connect(addr).await?;
  14.     Ok(tcp)
  15. }
复制代码
通过指定超时时间来对连接的建立监听。
读操作超时定时器

大部分HTTP请求,只有得到完整的数据才能进行处理,少部分如文件上传这种可以边上传边操作,而是否能开始操作关系到请求的响应时间。
读超时大概有以下的可能:
这造成客户端无法及时处理数据,可以报错好让客户端换备用线路或者备用服务器等以便及时的处理数据。
读操作我们不管服务端或者客户端,不管http/1.1或者http/2均由is_read_end字段来判定,在未读完当前请求的数据前,判断是否超时。
[code]pub fn poll_ready(    &mut self,    cx: &mut Context




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