Client sometimes only receives one message out of two #6275
-
I'm currently building a simple chat server and client, with the server based heavily off the chat example in the repo. It was working fine for a long time but I'm now running into an issue when I try and send two responses to the client sequentially. Once the client has connected successfully, I want to send two responses however sometimes only the first one is received on the client side.
send_response(
&mut user.bytes,
Response::Server(model::ServerResponse::JoinedServer {
username: name.clone(),
}),
)
.await;
send_response(
&mut user.bytes,
Response::Server(model::ServerResponse::JoinedRoom {
room_name: "main".to_string(),
}),
)
.await; and pub async fn send_response(stream: &mut Stream, res: Response) {
let res_bytes: Vec<u8> = res.into();
stream.send(Bytes::from(res_bytes)).await.unwrap();
<Framed<TcpStream, BytesCodec> as SinkExt<Bytes>>::flush(stream)
.await
.unwrap();
} (I added the flushing here to try and fix the issue but as far as I can tell it makes no difference.) And on the client side I use std::thread::spawn(move || {
rt.block_on(async move {
loop {
let mut buf = [0u8; 1024];
tokio::select! {
res = reader.read(&mut buf) => {
match res {
Ok(0) => todo!(),
Ok(n) => {
let res: model::Response = bincode::deserialize(&buf[0..n]).unwrap();
tx.send(res).unwrap();
},
Err(_) => todo!(),
}
}
task = recv.recv() => {
if let Some(task) = task {
tokio::spawn(handle_task_raw(writer.clone(), task));
}
}
}
}
});
}); The main loop of the client tries to read from this channel and display the responses: loop {
while let Ok(res) = rx.try_recv() {
state.handle_response(res);
}
terminal.draw(|f| ui(f, &state))?;
match event::poll(Duration::from_millis(100)) {
// snipped input handling code
}
} I'm out of ideas for why this behaviour is happening so any help would be much appreciated. Full code can be found here. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
When you read/write directly to a
You are using If you don't want this, you must use a different codec. For example the length delimited codec will keep track of message boundaries for you. It does this by writing the length of each message before the message so that it knows how many bytes to read to get the full message. |
Beta Was this translation helpful? Give feedback.
No, both sides must use the length delimited codec.
As for why you weren't getting errors, well, the splitting was probably happening in a lucky way.