feat: works
This commit is contained in:
119
src/main.rs
119
src/main.rs
@@ -63,23 +63,24 @@ struct RoomMessageDown {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RoomMessageDown {
|
impl RoomMessageDown {
|
||||||
fn create_error_reply(error_message: String) -> Self {
|
fn create_error_reply<S>(error_message: S) -> Self where S: Into<String> {
|
||||||
Self {
|
Self {
|
||||||
r#type: RoomMessageDownType::ReplyMessage,
|
r#type: RoomMessageDownType::ReplyMessage,
|
||||||
reply_code: Some(500),
|
reply_code: Some(500),
|
||||||
reply_message: Some(error_message),
|
reply_message: Some(error_message.into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_success_reply(success_message: String) -> Self {
|
fn create_success_reply<S>(success_message: S) -> Self where S: Into<String> {
|
||||||
Self {
|
Self {
|
||||||
r#type: RoomMessageDownType::ReplyMessage,
|
r#type: RoomMessageDownType::ReplyMessage,
|
||||||
reply_code: Some(200),
|
reply_code: Some(200),
|
||||||
reply_message: Some(success_message),
|
reply_message: Some(success_message.into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn create_peer_enter(peer_id: String) -> Self {
|
fn create_peer_enter<S>(peer_id: S) -> Self where S: Into<String> {
|
||||||
|
let peer_id = peer_id.into();
|
||||||
Self {
|
Self {
|
||||||
r#type: RoomMessageDownType::PeerEnter,
|
r#type: RoomMessageDownType::PeerEnter,
|
||||||
reply_code: Some(200),
|
reply_code: Some(200),
|
||||||
@@ -88,6 +89,12 @@ impl RoomMessageDown {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send(&self, tx: &UnboundedSender<Message>) {
|
||||||
|
if let Ok(mm) = serde_json::to_string(self) {
|
||||||
|
tx.unbounded_send(Message::Text(mm)).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tx = UnboundedSender<Message>;
|
type Tx = UnboundedSender<Message>;
|
||||||
@@ -112,6 +119,8 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
|
|
||||||
let (outgoing, incoming) = ws_stream.split();
|
let (outgoing, incoming) = ws_stream.split();
|
||||||
|
|
||||||
|
let mut is_admin = false;
|
||||||
|
let admin_pass = std::env::var("PASS").ok();
|
||||||
let mut room_id: Option<String> = None;
|
let mut room_id: Option<String> = None;
|
||||||
let mut client_id: Option<String> = None;
|
let mut client_id: Option<String> = None;
|
||||||
let broadcast_incoming = incoming.try_for_each(|msg| {
|
let broadcast_incoming = incoming.try_for_each(|msg| {
|
||||||
@@ -127,30 +136,70 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
Message::Pong(_) => {},
|
Message::Pong(_) => {},
|
||||||
Message::Binary(_) => {
|
Message::Binary(_) => {
|
||||||
warning!("Ignore binary message from: {:?} - {:?}", room_id, client_id);
|
warning!("Ignore binary message from: {:?} - {:?}", room_id, client_id);
|
||||||
let m = RoomMessageDown::create_error_reply("unknown error".into());
|
RoomMessageDown::create_error_reply("unknown error").send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Message::Text(msg) => {
|
Message::Text(msg) => {
|
||||||
let room_message = serde_json::from_str::<RoomMessage>(&msg);
|
if msg.is_empty() {
|
||||||
match room_message {
|
return future::ok(());
|
||||||
|
}
|
||||||
|
if msg == "/statics" {
|
||||||
|
tx.unbounded_send(Message::Text(
|
||||||
|
format!(
|
||||||
|
"room count: {}\npeer count: {}",
|
||||||
|
room_map.lock().unwrap().len(),
|
||||||
|
peer_map.lock().unwrap().len(),
|
||||||
|
)
|
||||||
|
)).ok();
|
||||||
|
return future::ok(());
|
||||||
|
}
|
||||||
|
if msg.starts_with("/pass ") {
|
||||||
|
let pass = &msg[6..];
|
||||||
|
if let Some(admin_pass) = &admin_pass {
|
||||||
|
if admin_pass == pass {
|
||||||
|
is_admin = true;
|
||||||
|
tx.unbounded_send(Message::Text("Admin password success".into())).ok();
|
||||||
|
} else {
|
||||||
|
tx.unbounded_send(Message::Text("Admin password error".into())).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return future::ok(());
|
||||||
|
}
|
||||||
|
if is_admin {
|
||||||
|
if msg == "/rooms" {
|
||||||
|
let rooms = room_map.lock().unwrap().keys().map(
|
||||||
|
|k| k.clone()
|
||||||
|
).collect::<Vec<_>>().join("\n");
|
||||||
|
tx.unbounded_send(Message::Text(format!("rooms:\n{}", rooms))).ok();
|
||||||
|
return future::ok(());
|
||||||
|
}
|
||||||
|
if msg.starts_with("/room ") {
|
||||||
|
let room_id = &msg[6..];
|
||||||
|
let room_map = room_map.lock().unwrap();
|
||||||
|
let mut client_ids = vec![];
|
||||||
|
if let Some(client_map) = room_map.get(room_id) {
|
||||||
|
for peer_client_id in client_map.keys() {
|
||||||
|
client_ids.push(peer_client_id.clone());
|
||||||
|
}
|
||||||
|
tx.unbounded_send(Message::Text(format!("clients in room {}:\n{}", room_id, client_ids.join("\n")))).ok();
|
||||||
|
} else {
|
||||||
|
tx.unbounded_send(Message::Text(format!("room not found: {}", room_id))).ok();
|
||||||
|
}
|
||||||
|
return future::ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let room_message = match serde_json::from_str::<RoomMessage>(&msg) {
|
||||||
|
Ok(room_message) => room_message,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warning!("Parse message: from: {:?} - {:?}, failed: {}", room_id, client_id, e);
|
warning!("Parse message: from: {:?} - {:?}, failed: {}", room_id, client_id, e);
|
||||||
let m = RoomMessageDown::create_error_reply(format!("Message parse failed: {}, message: {}", e, msg));
|
RoomMessageDown::create_error_reply(format!("Message parse failed: {}, message: {}", e, msg)).send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
return future::ok(());
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
Ok(room_message) => {
|
|
||||||
match room_message.r#type {
|
match room_message.r#type {
|
||||||
RoomMessageType::CreateOrEnter => {
|
RoomMessageType::CreateOrEnter => {
|
||||||
if let (Some(_), Some(_)) = (&room_id, &client_id) {
|
if let (Some(_), Some(_)) = (&room_id, &client_id) {
|
||||||
warning!("Client is already in room: {:?} - {:?}", room_id, client_id);
|
warning!("Client is already in room: {:?} - {:?}", room_id, client_id);
|
||||||
let m = RoomMessageDown::create_error_reply("Client is already in room".into());
|
RoomMessageDown::create_error_reply("Client is already in room").send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if let (Some(msg_room_id), Some(msg_client_id)) = (room_message.room_id, room_message.client_id) {
|
if let (Some(msg_room_id), Some(msg_client_id)) = (room_message.room_id, room_message.client_id) {
|
||||||
let mut room_map = room_map.lock().unwrap();
|
let mut room_map = room_map.lock().unwrap();
|
||||||
@@ -160,10 +209,7 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
Some(peer_addr) => {
|
Some(peer_addr) => {
|
||||||
if peer_addr == &addr {
|
if peer_addr == &addr {
|
||||||
information!("Duplicate enter to room: {:?} - {:?}", msg_room_id, msg_client_id);
|
information!("Duplicate enter to room: {:?} - {:?}", msg_room_id, msg_client_id);
|
||||||
let m = RoomMessageDown::create_success_reply("Duplicate enter to room".into());
|
RoomMessageDown::create_success_reply("Duplicate enter to room").send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
information!("Replace client: {:?} - {:?}, from {:?} -> {:?}", msg_room_id, msg_client_id, peer_addr, addr);
|
information!("Replace client: {:?} - {:?}, from {:?} -> {:?}", msg_room_id, msg_client_id, peer_addr, addr);
|
||||||
let tx = peer_map.lock().unwrap().remove(peer_addr);
|
let tx = peer_map.lock().unwrap().remove(peer_addr);
|
||||||
@@ -200,10 +246,7 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
room_id = Some(msg_room_id);
|
room_id = Some(msg_room_id);
|
||||||
client_id = Some(msg_client_id);
|
client_id = Some(msg_client_id);
|
||||||
} else {
|
} else {
|
||||||
let m = RoomMessageDown::create_error_reply("Room id and client id must both assigned".into());
|
RoomMessageDown::create_error_reply("Room id and client id must both assigned").send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -258,9 +301,7 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
data: Some(client_ids_data),
|
data: Some(client_ids_data),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
m.send(&tx);
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client_not_in_room(&tx);
|
client_not_in_room(&tx);
|
||||||
@@ -317,10 +358,7 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
peer_tx.unbounded_send(Message::Text(mm.clone())).ok();
|
peer_tx.unbounded_send(Message::Text(mm.clone())).ok();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let m = RoomMessageDown::create_error_reply(format!("Peer not found: {}", peer_id));
|
RoomMessageDown::create_error_reply(format!("Peer not found: {}", peer_id)).send(&tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -332,8 +370,6 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
future::ok(())
|
future::ok(())
|
||||||
});
|
});
|
||||||
@@ -352,10 +388,7 @@ async fn inner_handle_connection(peer_map: PeerMap, room_map: RoomMap, raw_strea
|
|||||||
|
|
||||||
fn client_not_in_room(tx: &UnboundedSender<Message>) {
|
fn client_not_in_room(tx: &UnboundedSender<Message>) {
|
||||||
information!("Client is not in room");
|
information!("Client is not in room");
|
||||||
let m = RoomMessageDown::create_error_reply("Client is not in room".into());
|
RoomMessageDown::create_error_reply("Client is not in room").send(tx);
|
||||||
if let Ok(mm) = serde_json::to_string(&m) {
|
|
||||||
tx.unbounded_send(Message::Text(mm)).ok();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn client_exit(room_map: &RoomMap, room_id: &Option<String>, client_id: &Option<String>) {
|
fn client_exit(room_map: &RoomMap, room_id: &Option<String>, client_id: &Option<String>) {
|
||||||
@@ -381,8 +414,8 @@ async fn main() -> Result<(), IoError> {
|
|||||||
|
|
||||||
// Create the event loop and TCP listener we'll accept connections on.
|
// Create the event loop and TCP listener we'll accept connections on.
|
||||||
let try_socket = TcpListener::bind(&addr).await;
|
let try_socket = TcpListener::bind(&addr).await;
|
||||||
let listener = try_socket.expect("Failed to bind");
|
let listener = try_socket.expect(&format!("Failed to bind ok: {}", addr));
|
||||||
println!("Listening on: {}", addr);
|
success!("Listening on: {}", addr);
|
||||||
|
|
||||||
// Let's spawn the handling of each connection in a separate task.
|
// Let's spawn the handling of each connection in a separate task.
|
||||||
while let Ok((stream, addr)) = listener.accept().await {
|
while let Ok((stream, addr)) = listener.accept().await {
|
||||||
|
|||||||
Reference in New Issue
Block a user