Облегченная библиотека, позволяющая отправлять и получать объекты через TCP или UDP. ObjectTranport стремится стать максимально простой и легкой сетевой структурой.
Доступны несколько вариантов сериализации, например Protobuf. Сериализация является инъекционной, и вы можете реализовать свою собственную.
ObjectTransport разделен на отдельные пакеты в зависимости от ваших потребностей и доступен на nuget. Дополнительную информацию см. в инструкциях по установке: https://github.com/RhynoVDS/ObjectTransport/wiki/Installation.
Вы можете запустить TCP-сервер с помощью следующего кода:
var server = ObjectTransport . Factory . CreateTCPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the TCP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
или вы можете запустить UDP-сервер
var server = ObjectTransport . Factory . CreateUDPServer ( )
. UseJSONserialization ( ) ;
. Build ( ) ;
//Start the UDP server on port 123
server . Start ( "127.0.0.1" , 123 ) ;
В этом примере у нас есть сценарий, в котором мы хотим обработать вход пользователя на сервер. Предположим, у нас есть простой класс под названием «LoginModel». На данный момент в этом классе есть только поле «Имя пользователя».
public class LoginModel
{
public string Username { get ; set ; }
}
Мы хотим, чтобы сервер получил этот объект и обработал его. Это можно сделать с помощью функции «Получить»:
server . Receive < LoginModel > ( lm =>
{
Console . WriteLine ( lm . Username ) ;
} )
. Execute ( ) ;
В приведенном выше коде мы указываем, что когда сервер получает объект типа «LoginModel», выполняется данная лямбда-выражение. Затем мы записываем имя пользователя в консоль.
Можно настроить несколько функций приема и обрабатывать другие типы:
server . Receive < LoginModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < LogOutModel > ( lm => .. . ) . Execute ( ) ;
server . Receive < PlayerPosition > ( lm => .. . ) . Execute ( ) ;
.. .
Вы можете запустить TCP-клиент с помощью следующего кода:
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 ) ;
Чтобы отправить объект по каналу, используйте функцию «Отправить»:
var loginRequest = new LoginModel ( )
loginRequest . Username = "TestUser" ;
client . Send ( loginRequest ) . Execute ( ) ;
В следующем примере мы покажем, как сервер/клиент может ответить на полученный объект.
В нашем предыдущем примере мы в настоящее время отправляем на сервер имя пользователя, но не пароль, что не очень безопасно. В этом примере мы обновляем нашу модель, добавляя в нее поле «Пароль»:
public class LoginModel
{
public string Username { get ; set ; }
public string Password { get ; set ; }
}
Нашему клиенту необходимо отправить запрос на вход на сервер, а теперь ему также необходимо будет отправить свой пароль. В связи с этим мы хотим обрабатывать любые ответы на наш запрос, включая успешность входа в систему. Чтобы справиться с этим, мы создаем два новых класса «LoginSuccess» и «LoginFailure».
public class LoginSuccess
{
public string Name { get ; set ; }
public string Password { get ; set ; }
}
public class LoginFailure
{
public string Message { get ; set ; }
}
В нашем клиентском коде мы теперь будем использовать функцию «Ответ» после отправки объекта входа в систему. Когда сервер отвечает на отправленный объект, клиент обрабатывает его ответы:
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 ( ) ;
В приведенном выше примере мы настраиваем два дескриптора ответа: один для обработки «LoginSuccess», а другой для обработки «LoginFailure».
На сервере мы будем использовать функцию «Ответить» после получения модели входа. При использовании этой функции нам нужно использовать функцию/лямбду, которая «вернет» объект, который будет отправлен обратно:
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 ( ) ;
При подключении нескольких клиентов можно указать, какому клиенту отправить сообщение, с помощью функции «Кому». В функции «Кому» можно указать несколько клиентов.
server . Send ( anObjectToSend )
. To ( client1 , client2 , .. . ClientN )
. Execute ( ) ;
Вы можете отправить всем клиентам, используя следующее.
//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
Также можно отправить всем клиентам и указать, кого исключить:
//Send to all clients except client 3
server . Send ( anObjectToSend )
. ToAllExcept ( client3 ) //Can exclude more eg: .ToAllExcept(client3,client2, ... clientN)
. Execute ( ) ;
Вы можете указать, что должно происходить, когда кто-то подключается или отключается:
//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 ) ) ;
При отправке объектов по UDP сообщение отправляется без надежности. Вы можете надежно включить UDP, выполнив следующие действия:
client . SetReliable ( ) ;
После выполнения указанной выше строки все отправляемые объекты будут отправлены надежно.
Другой вариант — надежно отправить только определенное сообщение. Это демонстрирует следующее:
client . Send ( anObjectToSend )
. Reliable ( ) ;
. Execute ( ) ;
Чтобы отключить одного или несколько клиентов от сервера, вы можете использовать функцию DisconnectClient:
server . DisconnectClient ( client1 , client2 , .. . clientN ) ;