Crate gns

source · []
Expand description

Rust wrapper for Valve GameNetworkingSockets.

Provides an abstraction over the low-level library. There are multiple advantage to use this abstraction:

  • Type safety: most of the low-level structures are wrapped and we leverage the type system to restrict the operations such that they are all safe.
  • High level: the library abstract most of the structure in such a way that you don’t have to deal with the low-level FFI plumbering required. The API is idiomatic, pure Rust.

Example

// **uwrap** must be banned in production, we use it here to extract the most relevant part of the library.

// Initial the global networking state. Note that this instance must be unique per-process.
let gns_global = GnsGlobal::get().unwrap();
let gns_utils = GnsUtils::new().unwrap();

// Create a new [`GnsSocket`], the index type [`IsCreated`] is used to determine the state of the socket.
// The [`GnsSocket::new`] function is only available for the [`IsCreated`] state. This is the initial state of the socket.
let gns_socket = GnsSocket::<IsCreated>::new().unwrap();

// We now do a transition from [`IsCreated`] to the [`IsClient`] state. The [`GnsSocket::connect`] operation does this transition for us.
// Since we are now using a client socket, we have access to a different set of operations.
let client = gns_socket.connect(Ipv6Addr::LOCALHOST, port).unwrap();

// Now that we initiated a connection, there is three operation we must loop over:
// - polling for new messages
// - polling for connection status change
// - polling for callbacks (low-level callbacks required by the underlying library).
// Important to know, regardless of the type of socket, whether it is in [`IsClient`] or [`IsServer`] state, theses three operations are the same.
// The only difference is that polling for messages and status on the client only act on the client connection, while polling for messages and status on a server yield event for all connected clients.

loop {
  // Run the low-level callbacks.
  client.poll_callbacks();

  // Receive a maximum of 100 messages on the client connection.
  // For each messages, print it's payload.
  let _actual_nb_of_messages_processed = client.poll_messages::<100, _>(|message| {
    println!(core::str::from_utf8(message.payload()).unwrap());
  });

  // Don't do anything with events.
  // One would check the event for connection status, i.e. doing something when we are connected/disconnected from the server.
  let _actual_nb_of_events_processed = client.poll_event::<100, _>(|_| {
  });

  // Sleep a little bit.
  std::thread::sleep(Duration::from_millis(10))
}

Re-exports

pub use gns_sys as sys;

Structs

Wrapper around steam sys::EResult. The library ensure that the wrapped value is not sys::EResult::k_EResultOK.

This is an empty type used to wrap the initialization/destruction of the low-level GameNetworkingSockets. On construction

Opaque wrapper around the low-level sys::HSteamListenSocket.

Wrapper around the low-level equivalent. This type is used to implements a more type-safe version of messages.

Opaque wrapper around the low-level sys::HSteamNetPollGroup.

GnsSocket is the most important structure of this library. This structure is used to create client (GnsSocket<IsClient>) and server (GnsSocket<IsServer>) sockets via the GnsSocket::connect and GnsSocket::listen functions. The drop implementation make sure that everything related to this structure is correctly freed, except the GnsGlobal and GnsUtils instances and the user has a strong guarantee that all the available operations over the socket are safe.

State of a GnsSocket that has been determined to be a client, usually via the GnsSocket::connect call. In this state, the socket hold the data required to receive and send messages.

Initial state of a GnsSocket. This state represent a socket that has not been used as a Server or Client implementation. Consequently, the state is empty.

State of a GnsSocket that has been determined to be a server, usually via the GnsSocket::listen call. In this state, the socket hold the data required to accept connections and poll them for messages.

Traits

Simple trait used to allow for a GnsSocket state to drop itself using the parent structure socket.

Common functions available for any GnsSocket state that is implementing it. Regardless of being a client or server, a ready socket will allow us to query for connection events as well as receive messages.

Type Definitions

A lane is represented by a Priority and a Weight

A lane Id.

A network message number. Simple alias for documentation.

Outcome of many functions from this library, basic type alias with steam sys::EResult as error. If the result is sys::EResult::k_EResultOK, the value can safely be wrapped, otherwise we return the error.

Lane priority

Lane weight