Skip to content

Commit

Permalink
Merge pull request amethyst#2001 from jstnlef/adding-network-error-ev…
Browse files Browse the repository at this point in the history
…ents

Add errors to the types of events which can be sent on the EventChannel
  • Loading branch information
jstnlef authored Dec 18, 2019
2 parents f5ef85e + 7cf554b commit a21a77f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 33 deletions.
9 changes: 8 additions & 1 deletion amethyst_network/src/simulation/events.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::simulation::Message;
use bytes::Bytes;
use std::net::SocketAddr;
use std::{io, net::SocketAddr};

/// Events which can be received from the network.
#[derive(Debug)]
Expand All @@ -10,4 +11,10 @@ pub enum NetworkSimulationEvent {
Connect(SocketAddr),
// A host has disconnected from us
Disconnect(SocketAddr),
// An error occurred while receiving a message.
RecvError(io::Error),
// An error occurred while sending a message.
SendError(io::Error, Message),
// An error occurred while managing connections.
ConnectionError(io::Error, Option<SocketAddr>),
}
8 changes: 4 additions & 4 deletions amethyst_network/src/simulation/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use std::net::SocketAddr;
#[derive(Debug, PartialEq, Eq)]
pub struct Message {
/// The destination to send the message.
pub(crate) destination: SocketAddr,
pub destination: SocketAddr,
/// The serialized payload itself.
pub(crate) payload: Bytes,
pub payload: Bytes,
/// The requirement around whether or not this message should be resent if lost.
pub(crate) delivery: DeliveryRequirement,
pub delivery: DeliveryRequirement,
/// The requirement around when this message should be sent.
pub(crate) urgency: UrgencyRequirement,
pub urgency: UrgencyRequirement,
}

impl Message {
Expand Down
17 changes: 12 additions & 5 deletions amethyst_network/src/simulation/transport/laminar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use amethyst_core::{
shrev::EventChannel,
};
use amethyst_error::Error;
pub use laminar::{Config as LaminarConfig, Socket as LaminarSocket};
pub use laminar::{Config as LaminarConfig, ErrorKind, Socket as LaminarSocket};
use laminar::{Packet, SocketEvent};

use bytes::Bytes;
Expand Down Expand Up @@ -67,13 +67,14 @@ impl<'s> System<'s> for LaminarNetworkSendSystem {
Write<'s, TransportResource>,
Write<'s, LaminarSocketResource>,
Read<'s, NetworkSimulationTime>,
Write<'s, EventChannel<NetworkSimulationEvent>>,
);

fn run(&mut self, (mut transport, mut socket, sim_time): Self::SystemData) {
fn run(&mut self, (mut transport, mut socket, sim_time, mut event_channel): Self::SystemData) {
if let Some(socket) = socket.get_mut() {
let messages = transport.drain_messages_to_send(|_| sim_time.should_send_message_now());

for message in messages.iter() {
for message in messages {
let packet = match message.delivery {
DeliveryRequirement::Unreliable => {
Packet::unreliable(message.destination, message.payload.to_vec())
Expand Down Expand Up @@ -107,8 +108,14 @@ impl<'s> System<'s> for LaminarNetworkSendSystem {
),
};

if let Err(e) = socket.send(packet) {
error!("There was an error when attempting to send packet: {:?}", e);
match socket.send(packet) {
Err(ErrorKind::IOError(e)) => {
event_channel.single_write(NetworkSimulationEvent::SendError(e, message));
}
Err(e) => {
error!("Error sending message: {:?}", e);
}
Ok(_) => {}
}
}
}
Expand Down
39 changes: 22 additions & 17 deletions amethyst_network/src/simulation/transport/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
use crate::simulation::{
events::NetworkSimulationEvent,
message::Message,
requirements::DeliveryRequirement,
timing::{NetworkSimulationTime, NetworkSimulationTimeSystem},
transport::{
TransportResource, NETWORK_RECV_SYSTEM_NAME, NETWORK_SEND_SYSTEM_NAME,
NETWORK_SIM_TIME_SYSTEM_NAME,
},
Message,
};
use amethyst_core::{
bundle::SystemBundle,
Expand All @@ -17,7 +17,7 @@ use amethyst_core::{
};
use amethyst_error::Error;
use bytes::Bytes;
use log::{error, warn};
use log::warn;
use std::{
collections::HashMap,
io::{self, Read as IORead, Write as IOWrite},
Expand Down Expand Up @@ -97,10 +97,10 @@ impl<'s> System<'s> for TcpStreamManagementSystem {
let s = match TcpStream::connect(message.destination) {
Ok(s) => s,
Err(e) => {
warn!(
"Error attempting to connection to {}: {:?}",
message.destination, e
);
event_channel.single_write(NetworkSimulationEvent::ConnectionError(
e,
Some(message.destination),
));
return;
}
};
Expand Down Expand Up @@ -146,7 +146,8 @@ impl<'s> System<'s> for TcpConnectionListenerSystem {
break;
}
Err(e) => {
error!("Error listening for connections: {}", e);
event_channel
.single_write(NetworkSimulationEvent::ConnectionError(e, None));
break;
}
};
Expand All @@ -163,18 +164,19 @@ impl<'s> System<'s> for TcpNetworkSendSystem {
Write<'s, TransportResource>,
Write<'s, TcpNetworkResource>,
Read<'s, NetworkSimulationTime>,
Write<'s, EventChannel<NetworkSimulationEvent>>,
);

fn run(&mut self, (mut transport, mut net, sim_time): Self::SystemData) {
fn run(&mut self, (mut transport, mut net, sim_time, mut channel): Self::SystemData) {
let messages = transport.drain_messages_to_send(|_| sim_time.should_send_message_now());
for message in messages.iter() {
for message in messages {
match message.delivery {
DeliveryRequirement::ReliableOrdered(Some(_)) => {
warn!("Streams are not supported by TCP and will be ignored.");
write_message(message, &mut net);
write_message(message, &mut net, &mut channel);
}
DeliveryRequirement::ReliableOrdered(_) | DeliveryRequirement::Default => {
write_message(message, &mut net);
write_message(message, &mut net, &mut channel);
}
delivery => panic!(
"{:?} is unsupported. TCP only supports ReliableOrdered by design.",
Expand All @@ -185,13 +187,14 @@ impl<'s> System<'s> for TcpNetworkSendSystem {
}
}

fn write_message(message: &Message, net: &mut TcpNetworkResource) {
fn write_message(
message: Message,
net: &mut TcpNetworkResource,
channel: &mut EventChannel<NetworkSimulationEvent>,
) {
if let Some((_, stream)) = net.get_stream(message.destination) {
if let Err(e) = stream.write(&message.payload) {
error!(
"There was an error when attempting to send message: {:?}",
e
);
channel.single_write(NetworkSimulationEvent::SendError(e, message));
}
}
}
Expand Down Expand Up @@ -239,7 +242,9 @@ impl<'s> System<'s> for TcpNetworkRecvSystem {
*active = false;
}
io::ErrorKind::WouldBlock => {}
_ => error!("Encountered an error receiving data: {:?}", e),
_ => {
event_channel.single_write(NetworkSimulationEvent::RecvError(e));
}
}
break;
}
Expand Down
10 changes: 5 additions & 5 deletions amethyst_network/src/simulation/transport/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use amethyst_core::{
};
use amethyst_error::Error;
use bytes::Bytes;
use log::error;
use std::{io, net::UdpSocket};

/// Use this network bundle to add the UDP transport layer to your game.
Expand Down Expand Up @@ -63,16 +62,17 @@ impl<'s> System<'s> for UdpNetworkSendSystem {
Write<'s, TransportResource>,
Write<'s, UdpSocketResource>,
Read<'s, NetworkSimulationTime>,
Write<'s, EventChannel<NetworkSimulationEvent>>,
);

fn run(&mut self, (mut transport, mut socket, sim_time): Self::SystemData) {
fn run(&mut self, (mut transport, mut socket, sim_time, mut channel): Self::SystemData) {
if let Some(socket) = socket.get_mut() {
let messages = transport.drain_messages_to_send(|_| sim_time.should_send_message_now());
for message in messages.iter() {
for message in messages {
match message.delivery {
DeliveryRequirement::Unreliable | DeliveryRequirement::Default => {
if let Err(e) = socket.send_to(&message.payload, message.destination) {
error!("There was an error when attempting to send packet: {:?}", e);
channel.single_write(NetworkSimulationEvent::SendError(e, message));
}
}
delivery => panic!(
Expand Down Expand Up @@ -118,7 +118,7 @@ impl<'s> System<'s> for UdpNetworkRecvSystem {
}
Err(e) => {
if e.kind() != io::ErrorKind::WouldBlock {
error!("Encountered an error receiving data: {:?}", e);
event_channel.single_write(NetworkSimulationEvent::RecvError(e));
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ The format is based on [Keep a Changelog][kc], and this project adheres to
- Adds `get` methods to the underlying net::transport resources ([#2005])
- Changed `SpriteSheetFormat::import_simple` to allow importing grid based `SpriteSheets` ([#2023])
Migration Note: Rons need to wrap their content in either Grid() or List()
- Added new Error options for `NetworkSimulationEvent`.

### Deprecated

Expand Down
6 changes: 5 additions & 1 deletion examples/net_server/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use amethyst::{
utils::application_root_dir,
Result,
};
use log::info;
use log::{error, info};
use std::net::TcpListener;

fn main() -> Result<()> {
Expand Down Expand Up @@ -114,6 +114,10 @@ impl<'a> System<'a> for SpamReceiveSystem {
NetworkSimulationEvent::Disconnect(addr) => {
info!("Client Disconnected: {}", addr);
}
NetworkSimulationEvent::RecvError(e) => {
error!("Recv Error: {:?}", e);
}
_ => {}
}
}
}
Expand Down

0 comments on commit a21a77f

Please sign in to comment.