Unexpected end of file during wasm sent package (work in native)
⚓ Rust 📅 2025-09-28 👤 surdeus 👁️ 12Hi everyone !
I work on a live version of freeciv game.
It uses the bevy engine, work in native and wasm target. After long time without tested my wasm version (I only checked its compile) I have a strange error in the network layer.
Unfortunately, I was unable to make a minimal reproduction code. I am not comfortable with wasm (I think bevy do a lot for me). I stopped trying after one day of try. I post this message in hope of someone have a good idea or a path to follow ![]()
There is the situation :
I use message-io for http server. I serve like this (entire module) :
let (handler, node_listener) = node::split::<Signal>();
info!(
"Starting TCP {} and Ws {}",
&self.tcp_listen_addr, &self.ws_listen_addr
);
handler
.network()
.listen(Transport::FramedTcp, &self.tcp_listen_addr)
.unwrap();
handler
.network()
.listen(Transport::Ws, &self.ws_listen_addr)
.unwrap();
// [...]
node_listener.for_each(move |event| match event {
node::NodeEvent::Network(event) => match event {
NetEvent::Connected(_, _) => unreachable!(), // There is no connect() calls.
NetEvent::Accepted(_, _) => {}
NetEvent::Message(endpoint, input_data) => {
let message = match bincode::deserialize::<ClientToServerMessage>(input_data) {
Ok(message) => message,
Err(error) => {
log::error!("Receive error: {error}");
return;
}
};
// Use message [...]
The native client (gui) part send message like this (entire file):
// message is `ClientToServerMessage`
let message = bincode::serialize(&message).unwrap();
// handler is from message-io
handler.network().send(server, &message);
The wasm client (gui) part use async-wsocket send message like this (entire file):
// message is `ClientToServerMessage`
let bytes = bincode::serialize(&message).unwrap();
tx.send(WsMessage::Binary(bytes)).await.unwrap();
The ClientToServerMessage definition is (partial here, entire file):
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ClientToServerMessage {
Network(ClientToServerNetworkMessage),
Game(ClientToServerGameMessage),
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ClientToServerNetworkMessage {
Hello(Client, Resolution),
Goodbye,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ClientToServerGameMessage {
Establishment(ClientToServerEstablishmentMessage),
InGame(ClientToServerInGameMessage),
}
// [...]
There are the facts:
- The native version works perfectly
- The wasm version success when send
ClientToServerMessage::Networkmessage but fail when sendClientToServerMessage::Gamemessage. Error in server part isio error: unexpected end of fileonbincode::deserialize::<ClientToServerMessage>(input_data) - The wasm version worked perfectly some weeks (month ?) ago. Before I made some refactor (not on network layer!) (I fail to git bisect, as I didn't check regularly the wasm version ...)
My feeling is that is related to ClientToServerMessage. But I don't understand why wasm version can work when send ClientToServerMessage::Network if fail with ClientToServerMessage::Game ...
If you feel very brave
, there is the way to reproduce locally (tested with Ubuntu, but should work on Windows and Mac):
To generate a world and start server:
- git clone git@github.com:buxx/civ.git
- git checkout fix-wasm-message
- cargo run --bin world --release -- ./world 5000 5000
- cargo run --release --bin server -- ./world
In other terminal, to start wasm http server :
- ./build_wasm.sh && http-server wasm
Then you can open http://127.0.0.1:7878/index.html . You cal click on Connect, then again Connect (here, ClientToServerMessage::Network message has been sent then correctly deserialized by server). Click now on Join after choose a country. You will see the io error: unexpected end of file error in server part.
If you've read this far, thank you!
1 post - 1 participant
🏷️ Rust_feed