Rust聊天室
本篇文章是Rust聊天室系列博客的第二篇——重构客户端和服务端的消息传递;
在这篇博客中对Rust聊天室的改进主要从以下三个方面入手
- 消息struct ,定义每一条消息的数据结构;
- 构建消息的字符串格式,在客户端和服务端之间采用JSON来传递信息;
- 解析字符串格式的消息;
一、定义消息的数据结构
首先定义一个文本消息的Struct,代码如下:
//define the text message struct
#[derive(Debug,Clone)]
pub struct TextMessage{
pub from : String, //the address of sender
pub to : String,//the address of receiver
pub content : String,//the content of msg
pub m_date : String //the date of the message(millis)
}
TextMessage主要包含有消息来源,消息接收,消息内容和消息发送时间这几个属性,前三个属性暂时定义为String,而m_date保存的是消息的发送时间。
二、构建消息的字符串格式
在聊天室项目的前期,我选择采用字符串流的形式来在服务端和客户端之间转换消息(后面可能直接使用JSON,但JSON实际也是字符串啦~),所以在构建消息之后需要将TextMessage对象转换为String,因此需要在TextMessage实现std::string::ToString
这个Trait,实现代码如下:
use std::string::ToString;
//the mothod to convert TextMessage to String
impl ToString for TextMessage{
fn to_string(&self) -> String{
format!("({},{},{},{})",self.from,self.to,self.content,self.m_date)
}
}
三、从字符串中获取消息
同样地,当接收到转发的字符串流后,我们不需要将整个字符串打印出来,而是会将字符串转换成TextMessage,然后打印我们需要的信息(即发送人、发送内容、发送时间等)这就要求我们的TextMessage实现std::str::FromStr
这个Trait了。
use std::str::FromStr;
use std::num::ParseIntError;、
//the mothod to convert String to TextMessage
impl FromStr for TextMessage{
type Err = ParseIntError;
fn from_str(s : &str) -> Result<Self,Self::Err>{
let message_info : Vec<&str> = s.trim_matches(|p| p == '(' || p == ')' ).split(",").collect();
let from = message_info[0].to_string();
let to = message_info[1].to_string();
let content = message_info[2].to_string();
// let m_date = message_info[3].parse::<i64>()?;
let m_date = message_info[3].to_string();
Ok(TextMessage{from,to,content,m_date})
}
}
四、消息发送时间属性
在这次改进中,我们引入了一个文本消息TextMessage的Struct来规范我们客户端发送的每一条信息,每一条信息都有一个发送时间,在这一次改进中,简单地使用了第三方库chrono
来获取时间,而且获取的还是utc
时间,简单的代码如下:
//create a simple message
let text_message = utils::TextMessage{
from : String::from("send_address"),
to : String::from("receive_address"),
content : message.clone(),
m_date : Utc::now().to_string()
};
五、下一次改进之处
- 客户端登录的用户名 ,在前面的demo中,没有设置client启动时登录用户名密码,所以在下一篇博客中,将改进方便消息转发;
- 对TextMessage更好地封装 ,从上面代码可以看出,在创建TextMessage对象时,我们时将TextMessage的各个属性设置为
pub
,方便我们直接访问,所以在下一次博客中,我们将对此进行更进一步地封装,避免直接访问属性。 - 拭目以待
六、总结
本文的实现工程可以访问该仓库。