Facepunch.Steamworks Wiki

Revision Difference

Creating_A_Socket_Server#524904

<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 )⤶ {⤶ Console.WriteLine( $"{data.Identity} is connecting" );⤶ }⤶ ⤶ public override void OnConnected( Connection connection, ConnectionInfo data )⤶ {⤶ connection.Accept();⤶ Console.WriteLine( $"{data.Identity} has joined the game" );⤶ }⤶ ⤶ public override void OnDisconnected( Connection connection, ConnectionInfo 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 )⤶ {⤶ 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 )⤶ {⤶ Console.WriteLine( $"{data.Identity} is connecting" );⤶ }⤶ ⤶ public void OnConnected( Connection connection, ConnectionInfo data )⤶ {⤶ connection.Accept();⤶ 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();⤶ }⤶ ```⤶ ⤶ ⤶ # 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>