群聊消息
创建群组
Socket.IO 房间是一个虚拟概念,允许你将 sockets(连接)分组在一起。处于同一房间的 sockets 可以轻松地彼此通信。当你想要向特定组的客户端广播消息而不是向所有连接的客户端广播时,这个特性非常有用。
变更 src/main.rs:
@@ -25,6 +25,13 @@ struct ChatData {
msg: String,
}
+#[derive(Serialize, Deserialize, Debug, Clone)]
+struct CreateGroupData {
+ sids: Vec<String>,
+ name: String,
+ id: String,
+}
+
type UserStore = HashMap<String, User>;
async fn on_connect(s: SocketRef) {
@@ -60,6 +67,20 @@ async fn on_connect(s: SocketRef) {
let to = data.to.clone();
s.to(to).emit("chat", data).ok();
});
+
+ // Create Room
+ s.on(
+ "create-group",
+ |s: SocketRef, Data::<CreateGroupData>(data)| async move {
+ for socket_id in data.sids.clone() {
+ s.within(socket_id).join(data.id.clone()).ok();
+ }
+ let room_id = data.id.clone();
+ let room_name = data.name.clone();
+ s.within(data.id.clone()).emit("create-group", data).ok();
+ println!("Room {} => {} created", room_id, room_name)
+ },
+ );
}
#[tokio::main]
sids
带有待创建群组的所有 socket ID。room_id
是一个唯一的字母数字字符串。相比于用户输入的房间名称,它更适合作为房间的内部标识。
s.within(...).emit(...)
通知所有参与者“新群组已经创建”。
转发群聊消息
变更 src/main.rs:
@@ -32,6 +32,13 @@ struct CreateGroupData {
id: String,
}
+#[derive(Serialize, Deserialize, Debug, Clone)]
+struct GroupChatData {
+ room: String,
+ speaker: String,
+ msg: String,
+}
+
type UserStore = HashMap<String, User>;
async fn on_connect(s: SocketRef) {
@@ -81,6 +88,14 @@ async fn on_connect(s: SocketRef) {
println!("Room {} => {} created", room_id, room_name)
},
);
+
+ s.on(
+ "group-chat",
+ |s: SocketRef, Data::<GroupChatData>(data)| async move {
+ let room = data.room.clone();
+ s.to(room).emit("group-chat", data).ok();
+ },
+ );
}
#[tokio::main]
to()
方法会选择指定房间内的所有客户端,除了当前 socket。
所以,s.to(room).emit(...)
转发消息给所有房间参与者,除了发送者自己。