ไลบรารีน้ำหนักเบาที่ให้คุณส่งและรับอ็อบเจ็กต์ผ่าน 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 ( ) ;
ในตัวอย่างต่อไปนี้ เราจะแสดงให้เห็นว่าเซิร์ฟเวอร์/ไคลเอนต์สามารถตอบกลับออบเจ็กต์ที่ได้รับได้อย่างไร
ในตัวอย่างก่อนหน้านี้ เรากำลังส่ง Username ไปยังเซิร์ฟเวอร์ แต่ไม่ใช่รหัสผ่าน ซึ่งไม่ปลอดภัยมากนัก ในตัวอย่างนี้ เราอัปเดตโมเดลของเราให้มีฟิลด์ "รหัสผ่าน":
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 ( ) ;
ในตัวอย่างข้างต้น เราตั้งค่าตัวจัดการการตอบสนอง 2 ตัว ตัวหนึ่งสำหรับจัดการ "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 ) ;