Wasm客户端发送Game类型消息时出现Unexpected end of file错误原因排查
Wasm平台发送Game类型消息时出现"Unexpected end of file"错误的排查
项目背景
我正在开发Freeciv游戏的在线版本,基于Bevy引擎,支持原生和Wasm双平台。此前长时间仅验证Wasm版本编译通过,未实际运行测试,近期发现网络层出现异常错误。由于无法编写最小复现代码,且对Wasm不熟悉(依赖Bevy完成大部分相关工作),多日尝试后暂时搁置问题。
核心架构与代码片段
服务器端(基于message-io库)
服务器同时监听TCP和WebSocket端口,收到消息后通过bincode反序列化为指定消息类型:
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!(), // 未调用connect() 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; } }; // 处理消息逻辑 [...]
原生客户端发送逻辑
使用message-io的handler发送序列化后的消息:
// message 为 ClientToServerMessage 类型 let message = bincode::serialize(&message).unwrap(); handler.network().send(server, &message);
Wasm客户端发送逻辑
使用async-wsocket库发送二进制消息:
// message 为 ClientToServerMessage 类型 let bytes = bincode::serialize(&message).unwrap(); tx.send(WsMessage::Binary(bytes)).await.unwrap();
消息结构定义(部分)
#[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), } // [...]
已知事实
- 原生版本运行完全正常
- Wasm版本发送
ClientToServerMessage::Network类型消息时,服务器能正常反序列化;但发送ClientToServerMessage::Game类型消息时,服务器执行bincode::deserialize会抛出io error: unexpected end of file错误 - Wasm版本数月前运行正常,之后进行了未涉及网络层的代码重构,但因未定期测试Wasm版本,无法通过Git bisect定位问题
本地复现步骤(Ubuntu验证通过,Windows/Mac理论适用)
- 克隆项目并启动服务器:
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
- 构建并启动Wasm HTTP服务器:
./build_wasm.sh && http-server wasm
- 打开页面操作:访问
http://127.0.0.1:7878/index.html,点击两次"Connect"(此时Network消息已成功发送并处理),选择国家后点击"Join",服务器端会出现目标错误。
问题
Wasm平台下发送ClientToServerMessage::Game类型消息时,出现"Unexpected end of file"错误的原因是什么?
内容的提问来源于stack exchange,提问作者bux
相关产品推荐
相关产品推荐

