A lightweight library that allows you to send and receive objects over TCP or UDP. ObjectTranport aims to be a network framework that is as simple and lightweight as possible.
Multiple serialization options are available such as Protobuf. Serialization is injectable and you can implement your own.
ObjectTransport is split into seperate packages based off your needs and available on nuget. Plese see installation instructions for more details: https://github.com/RhynoVDS/ObjectTransport/wiki/Installation
You can start a TCP server with the following code:
var server = ObjectTransport.Factory.CreateTCPServer()
.UseJSONserialization();
.Build();
//Start the TCP server on port 123
server.Start("127.0.0.1",123);
or you can start a UDP server
var server = ObjectTransport.Factory.CreateUDPServer()
.UseJSONserialization();
.Build();
//Start the UDP server on port 123
server.Start("127.0.0.1",123);
In this example we have a scenario where we want to handle a user logging into the server. Suppose we have a simple class called "LoginModel". For now this class only has the field "Username"
public class LoginModel
{
public string Username {get;set;}
}
We want the server to receive this object and handle it. This can be done using the "Receive" function:
server.Receive<LoginModel>(lm =>
{
Console.WriteLine(lm.Username);
})
.Execute();
In the above code, we specify that when the server Receives an object of type "LoginModel", execute the given lambda. We then write the Username to the console.
It is possible to set up multiple Receive functions and handle other types:
server.Receive<LoginModel>(lm => ... ).Execute();
server.Receive<LogOutModel>(lm => ... ).Execute();
server.Receive<PlayerPosition>(lm => ... ).Execute();
...
You can start a TCP client with the following code:
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);
To send an object over the channel, use the "Send" function:
var loginRequest = new LoginModel()
loginRequest.Username = "TestUser";
client.Send(loginRequest).Execute();
In the following example, we will show how a server/client can reply to a received object.
In our previous example, we are currently sending a Username to the server but not our password, which isn't very secure. In this example, we update our model to have a "Password" field:
public class LoginModel
{
public string Username {get;set;}
public string Password {get;set;}
}
Our client needs to send a login request to the server and will now need to send their password as well. Due to this, we want to handle any responses to our request including whether or not the login was successful. To handle this, we create two new classes "LoginSuccess" and "LoginFailure".
public class LoginSuccess
{
public string Name {get;set;}
public string Password {get;set;}
}
public class LoginFailure
{
public string Message {get;set;}
}
In our client code, we will now use the "Response" function after sending the login object. When the server replies to the object that was sent, the client will handle it's responses:
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();
In the above example, we setup 2 response handles, one to handle "LoginSuccess" and another to handle "LoginFailure".
On the server, we will use the "Reply" function after receiving a login model. When using this function we need use a function/lambda which will "return" an object that will be sent back:
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();
When multiple clients are connected, it is possible to specify which client to send a message to using the "To" function. You can specify multiple clients in the "To" function.
server.Send(anObjectToSend)
.To(client1,client2, ... ClientN)
.Execute();
You can send to all clients using the following.
//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
You can also send to all clients and specify who to exclude:
//Send to all clients except client 3
server.Send(anObjectToSend)
.ToAllExcept(client3) //Can exclude more eg: .ToAllExcept(client3,client2, ... clientN)
.Execute();
You can specify what should happen when someone connects or disconnects:
//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));
When sending objects over UDP, the message is sent without reliability. You can switch reliably on for UDP on with the following:
client.SetReliable();
After executing the above line, all objects that are sent will be sent reliably.
Another option is to send only a specific message reliably. The following demonstrates this:
client.Send(anObjectToSend)
.Reliable();
.Execute();
To disconnect one ore more clients from the server, you can use the DisconnectClient function:
server.DisconnectClient(client1,client2, ... clientN);