Revision Difference
Creating_A_Socket_Server#562835
<cat>code.networking</cat>
<title>Creating A Socket Server</title>
This will show you how to create a socket server, like the dedicated server in Rust.
There are a couple of ways to create your server .
# A Server Class
You can override SocketManager to create your class, like this:
```
public class MyServer : SocketManager
{
public override void OnConnecting( Connection connection, ConnectionInfo data )
{
base.OnConnecting(connection, data);⤶
connection.Accept();
Console.WriteLine( $"{data.Identity} is connecting" );
}
public override void OnConnected( Connection connection, ConnectionInfo data )
{
base.OnConnected(connection, data);⤶
Console.WriteLine( $"{data.Identity} has joined the game" );
}
public override void OnDisconnected( Connection connection, ConnectionInfo data )
{
base.OnDisconnected(connection, data);⤶
Console.WriteLine( $"{data.Identity} is out of here" );
}
public override void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
{
base.OnMessage(connection, identity, data, size, messageNum, recvTime, channel);⤶
Console.WriteLine( $"We got a message from {identity}!" );
// Send it right back
connection.SendMessage( data, size, SendType.Reliable );
}
}
```
Then you'd create/start your server like this
```
MyServer server = SteamNetworkingSockets.CreateNormalSocket<MyServer>( Data.NetAddress.AnyIp( 21893 ) );
```
# An Interface
It might be simpler for you to create it using an interface. This is useful if you already have a class you want to act as the server, rather than building the whole thing around the network system.
```
public class MyServer : ISocketManager
{
public void OnConnecting( Connection connection, ConnectionInfo data )
{
connection.Accept();
Console.WriteLine( $"{data.Identity} is connecting" );
}
public void OnConnected( Connection connection, ConnectionInfo data )
{
Console.WriteLine( $"{data.Identity} has joined the game" );
}
public void OnDisconnected( Connection connection, ConnectionInfo data )
{
Console.WriteLine( $"{data.Identity} is out of here" );
}
public void OnMessage( Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel )
{
Console.WriteLine( $"We got a message from {identity}!" );
// Send it right back
connection.SendMessage( data, size, SendType.Reliable );
}
}
```
Then you'd start your server like this, where myServer is an instance of a class with the ISocketManager interface.
```
SocketManager manager = SteamNetworkingSockets.CreateNormalSocket( Data.NetAddress.AnyIp( 21893 ), myServer );
```
# Which One?
It's up to you. Neither is better than the other, I just did it this way to give some flexibility.
<note>In Rust I used the interface approach because our network system has to derive from a specific class. It was cleaner to do it this way.
If I was starting from scratch I'd probably do the class method.
</note>
# Clients
You can get a list of clients via the SocketManager class.
```
//
// Kick everyone
//
foreach ( var connection in Connected )
{
connection.Close();
}
```
Client can connect with ConnectNormal or ConnectRelay and need to be stored with a ConnectionManager or a class that inherit from it :
```
MyConnectionManager hostConnection = SteamNetworkingSockets.ConnectRelay<MyConnectionManager>(hostSteamID);
```⤶
# Message Format⤶
⤶
```⤶
<warning> The Connection type must match between client and server; Either use CreateNormalSocket with ConnectNormal, or CreateRelaySocket with ConnectRelay. ⤶
</warning>⤶
⤶
# Message Format⤶
Messages formats aren't defined. That's up to you to figure out yourself. We just send the raw data from one connection to another.
<warning>Where possible try to use the Connection.Send method which takes an IntPtr. If you're passing byte[] or string then you're probably creating garbage unless you know what you're doing.</warning>