11个版本 (6个重大更新)
新 0.7.0 | 2024年8月24日 |
---|---|
0.6.0 | 2023年11月21日 |
0.5.3 | 2023年9月20日 |
0.4.1 | 2023年9月14日 |
0.1.0 | 2023年9月2日 |
#664 in 网络编程
每月124次下载
42KB
498 行
Bevy客户端服务器事件
Bevy的简单基于事件的客户端-服务器网络库。
轻松将事件从客户端发送到服务器或从服务器发送到客户端,无需担心序列化或网络传输细节。
基于renet/bevy_renet库构建,旨在简化通过网络发送的类型配置和管理。
目标:
- 简化网络设置和配置
- 轻松将任何类型从客户端发送到服务器或从服务器发送到客户端
要求:
serde
用于在您的类型上派生Serialize
和Deserialize
事件
以下事件对服务器很有用
EventWriter<StartServer>
- 发送此事件以启动服务器EventWriter<StopServer>
- 发送此事件以停止运行中的服务器EventReader<ClientConnected>
- 每次新客户端连接时都会收到EventReader<ClientDisconnected>
- 每次客户端断开连接时都会收到EventReader<ReceiveFromClient<T>>
- 当客户端向服务器发送类型T时收到EventWriter<SendToClient<T>>
- 发送此事件以便特定客户端接收类型TEventWriter<SendToClients<T>>
- 将此事件发送给所有已连接的客户端以接收类型 T
以下事件对客户端很有用
EventWriter<ConnectToServer>
- 发送此事件以连接到服务器EventWriter<DisconnectFromServer>
- 发送此事件以从服务器断开连接EventWriter<SendToServer<T>>
- 发送此事件以使服务器接收类型 TEventReader<ReceiveFromServer<T>>
- 服务器向客户端发送类型 T 时收到
客户端和服务器都可以接收 EventReader<NetcodeTransportError>
事件来处理网络错误。
示例
在 examples/
目录中有一些示例。
Ping
查看 examples/ping.rs
文件,了解一个简单的 ping-pong 示例。
在一个终端会话中,启动服务器: cargo run --example ping -- -s
在另一个终端会话中,连接客户端: cargo run --example ping
将客户端窗口置于焦点,按 ENTER
发送 Ping。服务器将以 Pong 响应。
在这个示例中,我们希望向服务器发送 Ping
事件并接收一个返回的 Pong
事件。
#[derive(Event, Serialize, Deserialize)]
pub struct Ping;
#[derive(Event, Serialize, Deserialize)]
pub struct Pong;
在设置我们的 App
时,我们需要将其传递给 client_server_events_plugin
宏并提供所有要通过网络发送的类型。
fn main() {
// ...
let mut app = App::new();
client_server_events_plugin!(
app,
Ping => NetworkConfig::default(),
Pong => NetworkConfig::default()
);
// ...
您可以提供特定于类型的网络配置,例如可靠性、重传时间、最大内存使用量等。
无论此实例将是服务器还是客户端,都应该运行此宏。
您可以选择启动服务器实例或作为客户端连接到服务器使用事件。
fn start_server(mut start_server: EventWriter<StartServer>) {
start_server.send(StartServer::default()); // Binds to 127.0.0.1:5000 with no encryption by default.
}
fn connect_as_client(mut connect_to_server: EventWriter<ConnectToServer>) {
connect_to_server.send(ConnectToServer::default()); // Connects to 127.0.0.1:5000 with no encryption by default.
}
然后您可以根据需要发送/接收事件。
fn update_client(
mut send_ping: EventWriter<SendToServer<Ping>>,
mut receive_pong: EventReader<ReceiveFromServer<Pong>>,
) {
// ...
send_ping.send(SendToServer { content: Ping });
// ...
for ReceiveFromServer { content } in receive_pong.read() {
// Do something with content (Pong).
// ...
}
}
fn update_server(
mut receive_ping: EventReader<ReceiveFromClient<Ping>>,
mut send_pong: EventWriter<SendToClient<Pong>>,
) {
for ReceiveFromClient { client_id, content } in receive_ping.read() {
// Do something with content (Ping).
send_pong.send(SendToClient {
client_id,
content: Pong,
});
}
}
功能示例
查看 examples/features.rs
文件,了解更多功能示例,如加密、广播、网络错误处理和客户端连接/断开事件。
在一个终端会话中,启动服务器: cargo run --example features -- -s
在另一个终端会话中,连接客户端: cargo run --example features
服务器和客户端将使用加密进行通信。
每 500 帧,服务器将广播其帧计数消息。
在服务器窗口上聚焦
- 按
ESC
键停止服务器 - 按
ENTER
键启动服务器
当焦点在客户端窗口时
- 按
ESC
键从服务器断开连接 - 按
ENTER
键重新连接到服务器 - 按
SPACE
键发送类型为PlayerMovement
的消息
服务器将以 ServerResponse
消息响应 PlayerMovement
消息。
其他网络库
创建这个库是因为我想找到一种最快、最简单的方式来通过网络发送类型。
其他解决方案似乎让我陷入了传输/网络/通道细节的困境。
这个库非常适合原型设计和小型客户端-服务器游戏。
一个带有更多功能的替代方案是 bevy_replicon。
一个更成熟的替代方案,具有更多可定制性的是 bevy_renet。
Bevy 兼容性
bevy | bevy_client_server_events |
---|---|
0.14 | 0.7 |
0.12 | 0.6 |
0.11 | 0.5 |
依赖项
~24MB
~438K SLoC