Establishing connections
Note
This is part of the Low Level Transport for advanced users only.
Host
To establish any connections, you must first create a Host.
Host constructor requires two parameters:
HostConfig contains all configuration values for construting a host. To see what each value does, check the API documentation. Default values should cover most cases. IHostListener is an interface which is used to listen for events such as connection requests or received packets. You can either directly implement IHostListener yourself or use a helper class HostEvents that implements it for you and exposes C# events you can use to register specific events. Most examples use HostEvents to make code easier to read.
A host is essentially an open UDP socket that is listening for packets on a specific port. Any host that has been succesfully constructed (and hasn't been disposed) is always listening for packets in the background. To shut down the host, it is recommended to use the Host.Shutdown()
method which gracefully over time in the background shuts down all the connections and disposes of the host, but if you would like to instantly close the socket and dispose of all resources, you can use Host.Dispose()
.
Peer
After creating your host, you can then establish connections on it by creating a Peer.
Construcing a peer usually requires three parameters:
A peer is a connection between two hosts that can be used to send messages across. You can only send messagess across the connection if the Peer.Connected
field is true. When establishing connections or after the connection has been terminated, Peer.Connected
will be false, indicating that messages cannot be sent or received.
Similarly as with hosts, PeerConfig holds all configuration values for the connection and IPeerListener is an interface used to listen for events. IPeerListener also has its own event based implementation PeerEvents that can be used to register specific events.
To create IPEndPoint's from an address string such as "127.0.0.1:80" you can use helper methods provided in IPResolver. If you're sure that the address string is not a hostname such as "superversus.com:80", then you can use the IPResolver.TryParse()
method. If you want to resolve the hostname to an ip address, you need to use one of the async methods that convert the "superversus.com" part to a valid address in the background.
There are two ways you can create peers:
- Requesting a new connection (client requesting a connection to a server)
- Accepting a connection request (server accepting a connection from a client)
Clients
If you have a host listening somewhere and you would like to establish a connection to it, you do it with the Host.Connect()
method. This method returns a peer that in the background starts sending connection requests until they are either accepted, rejected, or enough time passes without a response for the timeout disconnect event to trigger. During the connection phase you cannot send messages across.
If two clients use the Host.Connect()
method to attempt to connect to eachother at the same time, the connection will still be established. This can be used for establishing P2P connections.
using System;
using SuperNet.Netcode.Transport;
using SuperNet.Netcode.Util;
using UnityEngine;
public class ClientExample : MonoBehaviour {
private Host ClientHost;
private Peer ClientPeer;
public void Start() {
// Create client host
ClientHost = new Host(new HostConfig(), null);
// Register peer events
PeerEvents listener = new PeerEvents();
listener.OnConnect += OnPeerConnect;
listener.OnDisconnect += OnPeerDisconnect;
listener.OnReceive += OnPeerReceive;
// Parse address
IPEndPoint address = IPResolver.TryParse("192.168.1.123:1234")
// Start connecting
ClientPeer = ClientHost.Connect(address, new PeerConfig(), listener);
}
public void OnDestroy() {
ClientHost.Shutdown();
}
private void OnPeerConnect(Peer peer) {
Debug.Log("Peer connected.");
}
private void OnPeerDisconnect(
Peer peer,
Reader message,
DisconnectReason reason,
Exception exception
) {
Debug.Log("Peer disconnected.");
}
private void OnPeerReceive(
Peer peer,
Reader message,
MessageReceived info
) {
Debug.Log("Message received.");
}
}
Servers
If you have a host listening on a specific port for incoming connections and it receives a connection request, you can catch that and accept it by calling the ConnectionRequest.Accept()
method.
To receive anything on the server, you need make sure the port you are listening on is open. If you're behind a NAT, you can achive that with port forwarding. To learn how to establish connections without the need for port forwarding check out the Peer to Peer guide.
using System;
using SuperNet.Netcode.Transport;
using SuperNet.Netcode.Util;
using UnityEngine;
public class ServerExample : MonoBehaviour {
private Host ServerHost;
public void Start() {
// Register host events
HostEvents listener = new HostEvents();
listener.OnReceiveRequest += OnHostRequest;
// Create host config
HostConfig config = new HostConfig();
config.Port = 1234;
// Create server host
ServerHost = new Host(config, listener);
}
public void OnDestroy() {
ServerHost.Dispose();
}
private void OnHostRequest(ConnectionRequest request, Reader message) {
// Register peer events
PeerEvents listener = new PeerEvents();
listener.OnConnect += OnPeerConnect;
listener.OnDisconnect += OnPeerDisconnect;
listener.OnReceive += OnPeerReceive;
// Accept the request
request.Accept(new PeerConfig(), listener);
}
private void OnPeerConnect(Peer peer) {
Debug.Log("Peer " + peer.Remote + " connected.");
}
private void OnPeerDisconnect(
Peer peer,
Reader message,
DisconnectReason reason,
Exception exception
) {
Debug.Log("Peer " + peer.Remote + " disconnected.");
}
private void OnPeerReceive(
Peer peer,
Reader message,
MessageReceived info
) {
Debug.Log("Message received from peer " + peer.Remote + ".");
}
}
Keeping the connection alive
After a connection is established, internally peers keep the connection alive by periodically sending reliable ping messages. Whenever a ping message is sent, an acknowledgement message is requested back. When an acknowledgement is received, the peer updates the current round trip time (ping) value in milliseconds that can be accessed via the Peer.RTT
field. Whenever this field is updated, you will get notified via the IPeerListener event OnPeerUpdateRTT
. The field is updated when any acknowledgement is received, including custom reliable messages that you send, not just pings.
Disconecting
To disconnect, it is recommended to use the Peer.Disconnect()
method which sends a disconnect message and waits for the message to be acknowledged before terminating the connection. If you would like to instantly stop responding to all messages and dispose of all resources, you can use Peer.Dispose()
.