牛客Rust社区(web server Chapter 1)

找了很久牛客上面也有很多rust爱好者,但是Rust就没有类似Java求职、C++项目等圈子广场,希望官方可以提供一个Rust爱好交流圈子啥的。

C++项目者应该做过最多的就是web server服务器了,用Rust简单复现一个.

前置依赖:

toml 文件

tracing = "0.1.37"
tracing-subscriber = "0.3.17"
// 日志文件

第一步先注册一下全局日志,我不太喜欢println的方式打印,感觉那样太简陋且也没有可读性。

// 注册日志
tracing_subscriber::registry()
   .with(fmt::layer())
   .init();

然后是监听端口:127.0.0.1:8888

let listener = TcpListener::bind("127.0.0.1:8888").unwrap();
listener.incoming().map(Result::unwrap).for_each(handle_connection);
// handle_connection 是后面具体请求处理的方法,这儿先过滤,后面会讲

这样子就可以监听一个请求了,可以直接通过浏览器进行访问,但是我们怎么判断一个请求是否正确呢?这儿就得考虑http请求格式了。

可以通过这种方式在handle_connection方法中打印http_request看看格式,上面我写的方式是函数式编程,可能没怎么了解过rust的同学看起来估计可读性不高,我简单解释下:

  1. listener.incoming() 返回一个流(stream)的迭代器,该迭代器代表监听器接收到的传入连接。
  2. map(Result::unwrap) 对流中的每个元素执行 Result::unwrap 操作,将 Ok(T) 转换为对应的 T 值,忽略 Err 的情况。这是因为 listener.incoming() 返回的是一个 Result<TcpStream, Error> 类型,使用 Result::unwrap 可以提取出成功的 TcpStream 值。
  3. for_each(handle_connection) 对经过映射处理后的每个流应用 handle_connection 函数。for_each 方法接受一个闭包作为参数,并对流进行迭代并执行闭包中定义的操作。在这里,handle_connection 函数被应用于每个流上,实现对每个连接的处理。

故而上面其实最终传入handle_connection方法的都是一个TcpStream值。所以我们可以这么打印。

let buf_reader = BufReader::new(&mut stream);
let http_request: Vec<_> = buf_reader
   .lines()
   .map(|result| result.unwrap())
   .take_while(|line| !line.is_empty())
   .collect();

 tracing::info!("Request: {:#?}", http_request);

可以看到格式是这样的:

这儿我们判断比较简单,通过request的第一个值判断是否走http请求

let buf_reader = BufReader::new(&mut stream);
let request_line = buf_reader.lines().next().unwrap().unwrap();

let (status_line, filename) = match request_line.as_str() {
    "GET / HTTP/1.1" => ("HTTP/1.1 200 OK", "hello.html"),
    _ => ("HTTP/1.1 404 NOT FOUND", "404.html"),
};
let contents = fs::read_to_string(filename).unwrap();
let length = contents.len();
let response = format!("{status_line}\r\nContent-Length: {length}\r\n\r\n{contents}");
stream.write_all(response.as_bytes()).unwrap();

这儿的hello.html和 `404.html` 是我个人基于根目录创建的文件,这样子就可以给用户基本的展示了,这儿其实非常简单,就和用springboot写一个hello world的controller一样,当前是单线程的,肯定会出现阻塞的情况,下个文章准备写一个线程池来实现多线程不阻塞工作。

#Rust##Rust社区##悬赏#
技术面经+架构+八股 文章被收录于专栏

1. 关于当前公司所用技术架构(目前在某个短视频公司营销部门) 2. 关于个人之前接触的项目(存储、分布式、缓存) 3. 个人面经和之前的一块儿面试时的面经(核心部门 or ssp) 4. 个人简历模板 5. 手写的一些框架(时序数据库、编译器、hotring、亲缘性线程池等)

全部评论
我就是双飞本夸材料跨专业进计算机的。 老哥这是你去年一月的一个评论。 请问你跨考后悔吗,老实说小弟计算机专业有点想跨考材料了
点赞 回复 分享
发布于 2023-08-01 06:37 山西
对了,文中的handle_connection方法定义是这样的:fn handle_connection(mut stream: TcpStream) {...} 中间就是具体的stream的操作,比如在文中打印http_request
点赞 回复 分享
发布于 2023-07-29 22:51 北京

相关推荐

07-18 14:03
门头沟学院 Java
点赞 评论 收藏
分享
仁者伍敌:难怪小公司那么挑剔,让你们这些大佬把位置拿了
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
07-15 11:35
门头沟学院 Java
心里踏实多了,可以安心准备论文了
看不见我ffgh:牛哇佬,要不要来试一试pdd,部门氛围很好
京东开奖153人在聊
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务