Using messages-io: How to bidirectional?

Hello !

I'm writing a game with a client/server design. Clients send their updates and server must send over all client the game state changes. I'm taking a look to message-io.

When I take a look at the server example :

use message_io::node::{self};
use message_io::network::{NetEvent, Transport};

fn main() {
   // Create a node, the main message-io entity. It is divided in 2 parts:
   // The 'handler', used to make actions (connect, send messages, signals, stop the node...)
   // The 'listener', used to read events from the network or signals.
   let (handler, listener) = node::split::<()>();

   // Listen for TCP, UDP and WebSocket messages at the same time.
   handler.network().listen(Transport::FramedTcp, "0.0.0.0:3042").unwrap();
   handler.network().listen(Transport::Udp, "0.0.0.0:3043").unwrap();
   handler.network().listen(Transport::Ws, "0.0.0.0:3044").unwrap();

   // Read incoming network events.
   listener.for_each(move |event| match event.network() {
       NetEvent::Connected(_, _) => unreachable!(), // Used for explicit connections.
       NetEvent::Accepted(_endpoint, _listener) => println!("Client connected"), // Tcp or Ws
       NetEvent::Message(endpoint, data) => {
           println!("Received: {}", String::from_utf8_lossy(data));
           handler.network().send(endpoint, data);
       },
       NetEvent::Disconnected(_endpoint) => println!("Client disconnected"), //Tcp or Ws
   });
}

It is very clear to make a "Request -> Response". But, How can I send things from Server without waiting a Client message ? I'm trying to play with channels, but I'm a little bit lost.

To be clear, that's not how servers work. They don't randomly send data, unless you're dealing with a broadcast server, which simply keep on sending messages (like a radio station) and doesn't bother if the client picks it up or not (like whether you're listening to the radio or not is not of interest to the station). But a broadcast server usually doesn't accept requests from the client either. It might, but usually doesn't.
The more important question is, why do you want to asynchronously (that is, without the client sending a request) send something from the server to the client?

Okay, thanks for this information. To explain, I need the following :

  • An instance game (player which host) serve the server part : Each state modification (like soldiers new positions) must be sent to other client game instance (other players).
  • Other client game instances (other players) must be able to send state change requirements (like require soldier move) and receive state changes (like soldiers new positions)

It looks like NetEvent::Accepted gives you an Endpoint, which is how messages are addressed when sent over the handler. Endpoint implements clone, so during Accepted, you should be able to store that endpoint in some sort of collection that can be shared between that callback and your other server code.

handler in your example looks like it's a NodeHandler, which also implements clone. You should be able to spawn a thread that runs a "game loop" thread that regularly broadcasts the game's current state (or whatever your game needs) by referencing the collection of connected endpoints.

Disclaimer: I've never used message-io, just glanced at their docs.

1 Like

Roughly speaking, the instance needs to send two requests per "iteration" - one updating the server about it's player positions and one to query about other instance positions. Now in some games where positions hardly change, this may be wasteful or outright problematic (your position hardly changes, while the opponnent's position keeps on changing). For games where positions change frequently, you can choose an appropriate interval to "poll" and send these requests. You can also use piggybacking - the server sends the positions of opponents as a response to the positions of you sent to it.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.