本文使用rust+tokio开发一个即时聊天室,将使用到channel、websocket、stackless coroutine、select相关的知识
1 创建项目,命名为chatroom
updeMacBook-Pro:test aron$ cargo new chatroomCreated binary (application) `chatroom` package
2 添加项目依赖
在Cargo.toml添加如下内容tokio = { version ="1.11.0", features = ["full"] }支持websocket协议tokio-tungstenite ="0.15.0"futures-util ="0.3.16"日志组件log ="0.4.14"simple_logger ="1.13.0"uuid,我们用于标识UserIDuuid = { version ="0.8.2", features = ["serde","v4"] }
tokio-tungstenite 支持websocket
log simple_logger 用于日志输出
uuid 用于UserID的生成
3 添加聊天室结构体
pubstructChatRoom{user_map: HashMap<String, User>,event_rx_channel: UnboundedReceiver,}implChatRoom {创建聊天室pubfnnew(event_rx_channel: UnboundedReceiver) ->Self{ChatRoom {user_map: HashMap::new(),event_rx_channel,}}添加新用户pubfnadd_user(&mutself, user: User) {self.user_map.insert(user.id.clone(), user);}删除用户pubfnremove_user(&mutself, userId:String) {self.user_map.remove(&userId);}广播消息pubasyncfnbroadcast(&mutself, message: Message) {}处理事件pubasyncfnon_event_process(mutself) {}pubasyncfnjoin_room(raw_stream: TcpStream, system_sender: UnboundedSender, addr: SocketAddr) ->Result<(), IoError> {}}
先将ChatRoom的接口全部写出来,分别是添加用户,删除用户,广播消息,处理各类事件
user_map 用于保存聊天室内的全部用户
ChatRoom结构中包含的UnboundedReceiver,一个channel的接收器,用于接收各类事件。
4 事件处理
我们基于事件机制,处理聊天室的各种事件,如下列举了一些事件
JoinEvent用户加入聊天室事件,ChatRoom接收到该事件后,会将用户添加进聊天室
ExitEvent用户离开聊天室事件,ChatRoom接收到该事件后,会将用户移出聊天室 ExitEvent
MessageEvent用户发送消息事件,用户接收到新消息时,会将消息发送给ChatRoom用户广播
BroadcastEvent聊天室广播消息事件,ChatRoom将某个用户的消息广播给聊天室的所有用户
基于channel技术,我们将Event在用户和聊天室之间双向传递,然后针对每种event类型做出相应的操作,比如添加用户、删除用户、广播消息
[derive(Clone)]pubenumSystemEvent{JoinEvent {id:String,user: User,},ExitEvent {id:String,},MessageEvent {id:String,message: Message,},CommandEvent {command:i32,},BroadcastEvent {message: Message,},}
我们定义了一个enum类型的SytsemEvent结构,使用enum的好处是rust的enum非常强大,借助rust的match表达式,可以自动解析enum对应的事件的类型和属性,比如
matchevent {SystemEvent::JoinEvent { id, user } => {self.add_user(user);}SystemEvent::ExitEvent { id } => {}SystemEvent::MessageEvent { id, message } => {self.broadcast(message).await;}SystemEvent::CommandEvent { command } => {}_ => {}}
5 tokio select技术
下面举例说明下select的用法
asyncfna() {}asyncfnb() {}asyncfnc() {a().await;b().await;}asyncfnd() {select {a() => {}b() => {}}}asyncfne() {loop{select {a() => {}b() => {}}}}
上面是一段伪代码,定义了a和b两个函数
c函数中,a和b是按照顺序执行的
d函数中,使用了select,表示在等待a和b任意一个执行完成
e函数中,循环等待a和b的完成状态
在实际的开发中,也会遇到这种场景,同时等待两种或多种事件发生,这是就可以使用select技术
总结
本次先介绍聊天室开发所用到的相关基础技术,了解这些技术之后,我们就可以开始编写相关的代码了,后面的文章会将今天了解的相关概念编程成代码。
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容