Une bibliothèque légère qui vous permet d'envoyer et de recevoir des objets via TCP ou UDP. ObjectTranport vise à être un cadre réseau aussi simple et léger que possible.
Plusieurs options de sérialisation sont disponibles telles que Protobuf. La sérialisation est injectable et vous pouvez implémenter la vôtre.
ObjectTransport est divisé en packages distincts en fonction de vos besoins et disponibles sur nuget. Veuillez consulter les instructions d'installation pour plus de détails : https://github.com/RhynoVDS/ObjectTransport/wiki/Installation
Vous pouvez démarrer un serveur TCP avec le code suivant :
var server = ObjectTransport . Factory . CreateTCPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the TCP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
ou vous pouvez démarrer un serveur UDP
var server = ObjectTransport . Factory . CreateUDPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the UDP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
Dans cet exemple, nous avons un scénario dans lequel nous souhaitons gérer un utilisateur se connectant au serveur. Supposons que nous ayons une classe simple appelée « LoginModel ». Pour l'instant cette classe n'a que le champ "Nom d'utilisateur"
public class LoginModel
{
public string Username { get ; set ; }
}
Nous voulons que le serveur reçoive cet objet et le gère. Cela peut être fait en utilisant la fonction « Recevoir » :
server . Receive < LoginModel > ( lm =>
{
Console . WriteLine ( lm . Username ) ;
} )
. Execute ( ) ;
Dans le code ci-dessus, nous précisons que lorsque le serveur reçoit un objet de type "LoginModel", exécutez le lambda donné. Nous écrivons ensuite le nom d'utilisateur sur la console.
Il est possible de configurer plusieurs fonctions de réception et de gérer d'autres types :
server . Receive < LoginModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < LogOutModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < PlayerPosition > ( lm => .. . ) . Execute ( ) ;
.. .
Vous pouvez démarrer un client TCP avec le code suivant :
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 ) ;
Pour envoyer un objet sur le canal, utilisez la fonction « Envoyer » :
var loginRequest = new LoginModel ( )
loginRequest . Username = "TestUser" ;
client . Send ( loginRequest ) . Execute ( ) ;
Dans l'exemple suivant, nous montrerons comment un serveur/client peut répondre à un objet reçu.
Dans notre exemple précédent, nous envoyons actuellement un nom d'utilisateur au serveur mais pas notre mot de passe, qui n'est pas très sécurisé. Dans cet exemple, nous mettons à jour notre modèle pour avoir un champ « Mot de passe » :
public class LoginModel
{
public string Username { get ; set ; }
public string Password { get ; set ; }
}
Notre client doit envoyer une demande de connexion au serveur et devra désormais également envoyer son mot de passe. Pour cette raison, nous souhaitons traiter toutes les réponses à notre demande, y compris si la connexion a réussi ou non. Pour gérer cela, nous créons deux nouvelles classes « LoginSuccess » et « LoginFailure ».
public class LoginSuccess
{
public string Name { get ; set ; }
public string Password { get ; set ; }
}
public class LoginFailure
{
public string Message { get ; set ; }
}
Dans notre code client, nous allons désormais utiliser la fonction "Réponse" après l'envoi de l'objet de connexion. Lorsque le serveur répond à l'objet envoyé, le client gérera ses réponses :
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 ( ) ;
Dans l'exemple ci-dessus, nous configurons 2 handles de réponse, un pour gérer "LoginSuccess" et un autre pour gérer "LoginFailure".
Sur le serveur, nous utiliserons la fonction « Répondre » après avoir reçu un modèle de connexion. Lors de l'utilisation de cette fonction, nous devons utiliser une fonction/lambda qui "renverra" un objet qui sera renvoyé :
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 ( ) ;
Lorsque plusieurs clients sont connectés, il est possible de spécifier à quel client envoyer un message à l'aide de la fonction « À ». Vous pouvez spécifier plusieurs clients dans la fonction "À".
server . Send ( anObjectToSend )
. To ( client1 , client2 , .. . ClientN )
. Execute ( ) ;
Vous pouvez envoyer à tous les clients en utilisant les éléments suivants.
//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
Vous pouvez également envoyer à tous les clients et spécifier qui exclure :
//Send to all clients except client 3
server . Send ( anObjectToSend )
. ToAllExcept ( client3 ) //Can exclude more eg: .ToAllExcept(client3,client2, ... clientN)
. Execute ( ) ;
Vous pouvez spécifier ce qui doit se passer lorsque quelqu'un se connecte ou se déconnecte :
//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 ) ) ;
Lors de l'envoi d'objets via UDP, le message est envoyé sans fiabilité. Vous pouvez activer UDP de manière fiable avec les éléments suivants :
client . SetReliable ( ) ;
Après avoir exécuté la ligne ci-dessus, tous les objets envoyés le seront de manière fiable.
Une autre option consiste à envoyer uniquement un message spécifique de manière fiable. Ce qui suit le démontre :
client . Send ( anObjectToSend )
. Reliable ( ) ;
. Execute ( ) ;
Pour déconnecter un ou plusieurs clients du serveur, vous pouvez utiliser la fonction DisconnectClient :
server . DisconnectClient ( client1 , client2 , .. . clientN ) ;