Facepunch.Steamworks Wiki

Revision Difference

Creating_A_Socket_Server#526421

<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 ) { connection.Accept();⤶ 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 ) { connection.Accept();⤶ 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>