Eine schlanke Bibliothek, mit der Sie Objekte über TCP oder UDP senden und empfangen können. ObjectTranport zielt darauf ab, ein Netzwerk-Framework zu sein, das so einfach und leicht wie möglich ist.
Es stehen mehrere Serialisierungsoptionen zur Verfügung, beispielsweise Protobuf. Die Serialisierung ist injizierbar und Sie können Ihre eigene implementieren.
ObjectTransport ist je nach Bedarf in separate Pakete aufgeteilt und auf Nuget verfügbar. Weitere Informationen finden Sie in den Installationsanweisungen: https://github.com/RhynoVDS/ObjectTransport/wiki/Installation
Sie können einen TCP-Server mit dem folgenden Code starten:
var server = ObjectTransport . Factory . CreateTCPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the TCP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
oder Sie können einen UDP-Server starten
var server = ObjectTransport . Factory . CreateUDPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the UDP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
In diesem Beispiel haben wir ein Szenario, in dem wir einen Benutzer verwalten möchten, der sich am Server anmeldet. Angenommen, wir haben eine einfache Klasse namens „LoginModel“. Diese Klasse hat vorerst nur das Feld „Benutzername“
public class LoginModel
{
public string Username { get ; set ; }
}
Wir möchten, dass der Server dieses Objekt empfängt und verarbeitet. Dies kann über die Funktion „Empfangen“ erfolgen:
server . Receive < LoginModel > ( lm =>
{
Console . WriteLine ( lm . Username ) ;
} )
. Execute ( ) ;
Im obigen Code geben wir an, dass das angegebene Lambda ausgeführt wird, wenn der Server ein Objekt vom Typ „LoginModel“ empfängt. Anschließend schreiben wir den Benutzernamen in die Konsole.
Es ist möglich, mehrere Empfangsfunktionen einzurichten und andere Typen zu verarbeiten:
server . Receive < LoginModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < LogOutModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < PlayerPosition > ( lm => .. . ) . Execute ( ) ;
.. .
Sie können einen TCP-Client mit dem folgenden Code starten:
var client = ObjectTransport . Factory . CreateTCPClient ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the client and connect to the target IP address and port
client . Start ( "10.0.0.1" , 123 ) ;
Um ein Objekt über den Kanal zu senden, verwenden Sie die Funktion „Senden“:
var loginRequest = new LoginModel ( )
loginRequest . Username = "TestUser" ;
client . Send ( loginRequest ) . Execute ( ) ;
Im folgenden Beispiel zeigen wir, wie ein Server/Client auf ein empfangenes Objekt antworten kann.
In unserem vorherigen Beispiel senden wir derzeit einen Benutzernamen an den Server, aber nicht unser Passwort, das nicht sehr sicher ist. In diesem Beispiel aktualisieren wir unser Modell so, dass es ein Feld „Passwort“ enthält:
public class LoginModel
{
public string Username { get ; set ; }
public string Password { get ; set ; }
}
Unser Kunde muss eine Anmeldeanfrage an den Server senden und muss nun auch sein Passwort senden. Aus diesem Grund möchten wir alle Antworten auf unsere Anfrage bearbeiten, einschließlich der Frage, ob die Anmeldung erfolgreich war oder nicht. Um dies zu bewältigen, erstellen wir zwei neue Klassen „LoginSuccess“ und „LoginFailure“.
public class LoginSuccess
{
public string Name { get ; set ; }
public string Password { get ; set ; }
}
public class LoginFailure
{
public string Message { get ; set ; }
}
In unserem Client-Code werden wir nun nach dem Senden des Login-Objekts die Funktion „Response“ verwenden. Wenn der Server auf das gesendete Objekt antwortet, verarbeitet der Client seine Antworten:
var transport = ObjectTransport . Factory . CreateTCPClient ( "10.0.0.1" , 123 ) ;
var loginRequest = new LoginModel ( ) ;
loginRequest . Username = "TestUser" ;
loginRequest . Password = "A password" ;
transport . Send ( loginRequest )
. Response < LoginSuccess > ( ls => {
Console . WriteLine ( "Welcome Back {0}" , ls . Name ) ;
} )
. Response < LoginFailure > ( lr => {
Console . WriteLine ( lr . Message )
} )
. Execute ( ) ;
Im obigen Beispiel richten wir zwei Antworthandles ein, eines für die Verarbeitung von „LoginSuccess“ und eines für die Verarbeitung von „LoginFailure“.
Auf dem Server nutzen wir nach Erhalt eines Login-Modells die Funktion „Antworten“. Wenn wir diese Funktion verwenden, müssen wir eine Funktion/Lambda verwenden, die ein Objekt „zurückgibt“, das zurückgesendet wird:
server . Receive < LoginModel > ( )
. Reply ( lr => {
string user = string . empty ;
//Check if login is valid
if ( utilities . Login ( lr , out user ) )
{
//Return an object back to the client
var response = new LoginSuccess ( ) ;
response . Message = "Login Successful" ;
response . Name = user ;
return response ;
}
else
{
//Return an object back to the client
var response = new LoginFailure ( ) ;
response . Message = "Login Failed" ;
return response ;
}
} )
. Execute ( ) ;
Wenn mehrere Clients verbunden sind, kann über die Funktion „An“ festgelegt werden, an welchen Client eine Nachricht gesendet werden soll. Sie können in der Funktion „An“ mehrere Kunden angeben.
server . Send ( anObjectToSend )
. To ( client1 , client2 , .. . ClientN )
. Execute ( ) ;
Sie können Folgendes an alle Kunden senden:
//Send to all clients
server . Send ( anObjectToSend )
. ToAll ( )
. Execute ( ) ;
//Note that you don't actually need to specify ToAll anymore. By default the API will send to all
Sie können auch an alle Kunden senden und angeben, wen Sie ausschließen möchten:
//Send to all clients except client 3
server . Send ( anObjectToSend )
. ToAllExcept ( client3 ) //Can exclude more eg: .ToAllExcept(client3,client2, ... clientN)
. Execute ( ) ;
Sie können festlegen, was passieren soll, wenn jemand eine Verbindung herstellt oder trennt:
//Setup onconnect handler
transport . OnClientConnect ( c => Console . WriteLine ( "A client has connected with ip {0}" , c . IPAddress ) ) ;
//Setup onDisconnect handler
transport . OnClientDisconnect ( c => Console . WriteLine ( "A client has disconnected with ip {0}" , c . IPAddress ) ) ;
Beim Senden von Objekten über UDP wird die Nachricht ohne Zuverlässigkeit gesendet. Sie können UDP wie folgt zuverlässig einschalten:
client . SetReliable ( ) ;
Nach dem Ausführen der obigen Zeile werden alle gesendeten Objekte zuverlässig gesendet.
Eine andere Möglichkeit besteht darin, nur eine bestimmte Nachricht zuverlässig zu senden. Das Folgende zeigt dies:
client . Send ( anObjectToSend )
. Reliable ( ) ;
. Execute ( ) ;
Um einen oder mehrere Clients vom Server zu trennen, können Sie die DisconnectClient-Funktion verwenden:
server . DisconnectClient ( client1 , client2 , .. . clientN ) ;