Skip to content

Commit

Permalink
Add bevy_matchbox examples
Browse files Browse the repository at this point in the history
  • Loading branch information
johanhelsing committed Nov 14, 2023
1 parent 777dec5 commit 25f7e2c
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 0 deletions.
25 changes: 25 additions & 0 deletions bevy_matchbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,28 @@ cfg-if = "1.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
matchbox_signaling = { version = "0.7", path = "../matchbox_signaling", optional = true }
async-compat = { version = "0.2", optional = true }

[dev-dependencies]
bevy = { version = "0.12", default-features = false, features = [
"bevy_winit",
"bevy_render",
"bevy_pbr",
"bevy_core_pipeline",
"bevy_ui",
"bevy_text",
"bevy_asset",
"ktx2",
"zstd",
"tonemapping_luts",
"webgl2",
# gh actions runners don't like wayland
"x11",
] }

[[example]]
name = "hello_host"
required-features = ["signaling"]

[[example]]
name = "hello_signaling"
required-features = ["signaling"]
45 changes: 45 additions & 0 deletions bevy_matchbox/examples/hello.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Sends messages periodically to all connected peers (or host if connected in
//! a client server topology).
use bevy::{prelude::*, time::common_conditions::on_timer, utils::Duration};
use bevy_matchbox::prelude::*;

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, start_socket)
.add_systems(Update, receive_messages)
.add_systems(
Update,
send_message.run_if(on_timer(Duration::from_secs(5))),
)
.run();
}

fn start_socket(mut commands: Commands) {
let socket = MatchboxSocket::new_reliable("ws://localhost:3536/hello");
commands.insert_resource(socket);
}

fn send_message(mut socket: ResMut<MatchboxSocket<SingleChannel>>) {
let peers: Vec<_> = socket.connected_peers().collect();

for peer in peers {
let message = "Hello";
info!("Sending message: {message:?} to {peer}");
socket.send(message.as_bytes().into(), peer);
}
}

fn receive_messages(mut socket: ResMut<MatchboxSocket<SingleChannel>>) {
for (peer, state) in socket.update_peers() {
info!("{peer}: {state:?}");
}

for (_id, message) in socket.receive() {
match std::str::from_utf8(&message) {
Ok(message) => info!("Received message: {message:?}"),
Err(e) => error!("Failed to convert message to string: {e}"),
}
}
}
77 changes: 77 additions & 0 deletions bevy_matchbox/examples/hello_host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//! Runs both signaling with server/client topology and runs the host in the same process
//!
//! Sends messages periodically to all connected clients.
use bevy::{
app::ScheduleRunnerPlugin, log::LogPlugin, prelude::*, time::common_conditions::on_timer,
utils::Duration,
};
use bevy_matchbox::{matchbox_signaling::SignalingServer, prelude::*};
use std::net::{Ipv4Addr, SocketAddrV4};

fn main() {
App::new()
// .add_plugins(DefaultPlugins)
.add_plugins((
MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32(
1. / 120., // be nice to the CPU
))),
LogPlugin::default(),
))
.add_systems(Startup, (start_signaling_server, start_host_socket).chain())
.add_systems(Update, receive_messages)
.add_systems(
Update,
send_message.run_if(on_timer(Duration::from_secs(5))),
)
.run();
}

fn start_signaling_server(mut commands: Commands) {
info!("Starting signaling server");
let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 3536);
let signaling_server = MatchboxServer::from(
SignalingServer::client_server_builder(addr)
.on_connection_request(|connection| {
info!("Connecting: {connection:?}");
Ok(true) // Allow all connections
})
.on_id_assignment(|(socket, id)| info!("{socket} received {id}"))
.on_host_connected(|id| info!("Host joined: {id}"))
.on_host_disconnected(|id| info!("Host left: {id}"))
.on_client_connected(|id| info!("Client joined: {id}"))
.on_client_disconnected(|id| info!("Client left: {id}"))
.cors()
.trace()
.build(),
);
commands.insert_resource(signaling_server);
}

fn start_host_socket(mut commands: Commands) {
let socket = MatchboxSocket::new_reliable("ws://localhost:3536/hello");
commands.insert_resource(socket);
}

fn send_message(mut socket: ResMut<MatchboxSocket<SingleChannel>>) {
let peers: Vec<_> = socket.connected_peers().collect();

for peer in peers {
let message = "Hello, I'm the host";
info!("Sending message: {message:?} to {peer}");
socket.send(message.as_bytes().into(), peer);
}
}

fn receive_messages(mut socket: ResMut<MatchboxSocket<SingleChannel>>) {
for (peer, state) in socket.update_peers() {
info!("{peer}: {state:?}");
}

for (_id, message) in socket.receive() {
match std::str::from_utf8(&message) {
Ok(message) => info!("Received message: {message:?}"),
Err(e) => error!("Failed to convert message to string: {e}"),
}
}
}
39 changes: 39 additions & 0 deletions bevy_matchbox/examples/hello_signaling.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! Runs a signaling server with server/client topology as a headless bevy
//! application.
use bevy::{app::ScheduleRunnerPlugin, log::LogPlugin, prelude::*, utils::Duration};
use bevy_matchbox::{matchbox_signaling::SignalingServer, prelude::*};
use std::net::{Ipv4Addr, SocketAddrV4};

fn main() {
App::new()
.add_plugins((
MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32(
1. / 120., // be nice to the CPU
))),
LogPlugin::default(),
))
.add_systems(Startup, (start_signaling_server).chain())
.run();
}

fn start_signaling_server(mut commands: Commands) {
info!("Starting signaling server");
let addr = SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 3536);
let signaling_server = MatchboxServer::from(
SignalingServer::client_server_builder(addr)
.on_connection_request(|connection| {
info!("Connecting: {connection:?}");
Ok(true) // Allow all connections
})
.on_id_assignment(|(socket, id)| info!("{socket} received {id}"))
.on_host_connected(|id| info!("Host joined: {id}"))
.on_host_disconnected(|id| info!("Host left: {id}"))
.on_client_connected(|id| info!("Client joined: {id}"))
.on_client_disconnected(|id| info!("Client left: {id}"))
.cors()
.trace()
.build(),
);
commands.insert_resource(signaling_server);
}

0 comments on commit 25f7e2c

Please sign in to comment.