Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

High Performance Networking

License

Apache-2.0, Apache-2.0 licenses found

Licenses found

Apache-2.0
LICENSE
Apache-2.0
Licence.txt
NotificationsYou must be signed in to change notification settings

ReferenceType/StandardNetworkLibrary

Repository files navigation

High Performance, easy to use network library supporting 16k+ concurrent clients on all provided topologies.
Designed for distributed realtime concurrent applications over LAN or Internet.
Provides infrastructure for high throughput message passing, P2P, Nat Traversal, Reliable Udp.
This repository consist of main core assembly and several serialization spesific sub assemblies.

Please check outWiki page for detailed documentation.

Core Network Library

Network Library, Includes all logic associated with the network systems, starting from raw bytes to abstractions such as P2P lobbies. It provides generic templates to be used with any type of serialization.

Low Level

Plug&Play high performance models, working with raw bytes. Also used as base for higher level models.

  • Tcp Server/Client model with dynamic buffering and queueing sub systems, bytes can come fragmented like regular sockets.
  • Tcp Byte Message Server/Client where bytes are sent with 4 byte lenght header. It ensure atomic message delivery without fragmentation.
  • Udp Server/Client udp system where a server is emulated with optimised for performance.
  • Reliable Udp Client/Server where modern TCP protocol is implemented over Udp.
  • Secure variants of all of the above(SSL with TLS for Tcp, Symetric Key AES for Udp).

High Level

Involves generic models which can work with any serialization protocol.

  • Generic Message Server/Client designed to send and receive serialized messages atomically.
  • Generic MessageProtocol Server/client similar to above, but with addition of "MessageEnvelope" carrier class, used as header/metadata.
  • P2P Relay Client/Server where Peers(Clients) discover each other via Relay server, can use Udp/Rudp/Tcp to communicate. Supports Tcp&Udp Holepunch.
  • P2P Room/Lobby Server/Client extention of Relay model where peers can define a room, similar to game matchmaking servers.

Internal Features

Message Buffering/Queueing

  • Tcp models come with a buffering/queueing system. This system is activated only during high load.In a nutsell, if the socket is busy sending, next messages are buffered/queued and stiched together. When the socket becomes available again, sent as batch. Its like Naggle, but without sacrificing the fast sends on moderate/low traffic.
  • This improves the throughput of small messages quite significantly (1000 fold compared to naive sends) as shown on benchmarks.

Advanced Memory Management

  • Library implements "Shared Thread Local Memory Pool", where all byte arrays and the stream backing buffers are rented from.
  • As an example, RelayServer can relay 21 Gigabyte/s Udp traffic between 1000 clients using 36 mb process memory with 0 GC Colections.

Build In Serialization

  • Library provides high performance binary encoders for primitive and well known types and employs static srialization for internal message types and carrier classes with smallest possible byte size.

Library is tested with as many clients as OS(Windows) supports (around 16k dynamic ports). Data reliability includung RUDP is tested over the internet extensively.Nat Traversal Udp holepunching is also tested over the internet with success.

Note: Libary has unsafe code and stack memory allocations. Unsafe sections are well tested and not subject to change.

Sub Assemblies

Generic models from main assembly are implemented with the spesific serializer.Reason for this division is to avoid unnecessary dependencies.All method signatures and usage are identical.It includes:

  • Protobuf-Net
  • MessagePack
  • NetSerializer
  • System.Text.Json

Supported Runtimes

  • .NET Standard 2.0+
  • Up to .NET 8

Nuget Packages are available:

Core Network LibraryProtobufMessagePackNetSeralizerJson
NuGetNuGetNuGetNuGetNuGet

Benchmarks

Infinite Echo benchmarks are done by sending set of messages to server and getting echo response. Each response causes new request. Each server response is counted as 1 Echo.

  • Separate client and server applications are used for the tests.
  • Tests are done on my personal laptop with CPU AMD Ryzen 7 5800H.
  • Benchmark programs are provided in the project.

TCP/SSL Byte Message Server

1000 seed messages (32 bytes message + 4 header) each:

AMD Ryzen 7 5800H Laptop

Mumber Of ClientsTCP Echo per SecondSSL Echo per Second
10053,400,00041,600,000
100043,600,00022,200,000
500043,400,00021,800,000
1000042,800,00021,700,000

Intel i9 13980HX Laptop

Mumber Of ClientsTCP Echo per SecondSSL Echo per Second
100128,800,00079,400,000
1000110,400,00072,100,000
5000102,100,00067,500,000
10000100,500,00065,500,000

MessageProtocol

1000 seed message envelopes ( 32 byte payload, 48 byte total):

AMD Ryzen 7 5800H Laptop

Mumber Of ClientsProtobuf Echo per SecondSecure Protobuf Echo per Second
1009,440,0008,050,000
10008,780,0007,480,000
50008,360,0007,390,000
100008,340,0007,350,000

Intel i9 13980HX Laptop

Mumber Of ClientsProtobuf Echo per SecondSecure Protobuf Echo per Second
10031,200,00020,650,000
100030,500,00019,500,000
500028,200,00017,650,000
1000026,400,00016,000,000

Note

This benchmarks is only sending message envelope with raw byte payload. For serialization spesific performance please refer to:SerializationBenchmarks

Quick Documentation & Code Samples

Byte Message TCP Server/Client

For Detailed info Check outAsyncTcpClient/ServerandByteMessageTcpClient/Server

Any chunk of byte array or array segment will reach the destination without fragmentation.

privatestaticvoidExampleByteMessage(){ByteMessageTcpServerserver=newByteMessageTcpServer(20008);server.OnBytesReceived+=ServerBytesReceived;server.StartServer();ByteMessageTcpClientclient=newByteMessageTcpClient();client.OnBytesReceived+=ClientBytesReceived;client.Connect("127.0.0.1",20008);client.SendAsync(Encoding.UTF8.GetBytes("Hello I'm a client!"));voidServerBytesReceived(GuidclientId,byte[]bytes,intoffset,intcount){Console.WriteLine(Encoding.UTF8.GetString(bytes,offset,count));server.SendBytesToClient(clientId,Encoding.UTF8.GetBytes("Hello I'm the server"));}voidClientBytesReceived(byte[]bytes,intoffset,intcount){Console.WriteLine(Encoding.UTF8.GetString(bytes,offset,count));}}
output:Hello I'm a client!Hello I'm the server

Note: Important performance setting here is whether to use a buffer or a queue as buffering policy. Use Buffer if messages are mainly regions of byte[] such as (buffer, offset,count).Use Queue if the messages are full byte[] (0 to end).

client.GatherConfig=ScatterGatherConfig.UseQueue;server.GatherConfig=ScatterGatherConfig.UseBuffer;


For SSL variants difference is:

varccert=newX509Certificate2("client.pfx","greenpass");// null certificate or default constructor will generate self signed certificateclient=newSslByteMessageClient(ccert);varscert=newX509Certificate2("server.pfx","greenpass");// null certificate or default constructor will generate self signed certificateserver=newSslByteMessageServer(8888,scert);// You can override the SSL cerificate validation callbackserver.RemoteCertificateValidationCallback+= ...client.RemoteCertificateValidationCallback+= ...

For more info check outSSLClient/Server AndSSLByteMessageClient/Server

Base Server/Client where raw bytes are transfered. Method and callback signarures are identical to byte message models.There is no protocol implemented over base Server/Client, hence bytes may come fragmented depending on your MTU size.

AsyncTcpServerserver=newAsyncTcpServer(port:20000);AsyncTpcClientclient=newAsyncTpcClient();// SSL variant// null certificate or default constructor will generate self signed certificatevarccert=newX509Certificate2("client.pfx","greenpass");varscert=newX509Certificate2("server.pfx","greenpass");SslServerserver=newSslServer(2000,scert);SslClientclient=newSslClient(ccert);

Serialized Networks

Serialized Networks are implementations of generic classes provided by Core LibraryIt is applicable to all serialization protocols.

For more info :Serialised Network
Examples here is only given for Protobuf-net, but signature is identical for any other provided serialization protocol(MessagePack, Json etc).

Protobuf Example

Implements a server client model where serialized messages are transfered atomically.Declare your type:

[ProtoContract]classSampleMessage{[ProtoMember(1)]publicstringsample;}
PureProtoServerserver=newPureProtoServer(11234);server.StartServer();server.BytesReceived+=(clientId,bytes,offset,count)=>{SampleMessagemsg=server.Serializer.Deserialize<SampleMessage>(bytes,offset,count);Console.WriteLine(msg.sample);msg.sample="Jesse Lets cook";server.SendAsync(clientId,msg);};PureProtoClientclient=newPureProtoClient();client.Connect("127.0.0.1",11234);client.BytesReceived+=(bytes,offset,count)=>{SampleMessagemsg=client.Serializer.Deserialize<SampleMessage>(bytes,offset,count);Console.WriteLine(msg.sample);};client.SendAsync(newSampleMessage(){sample="Yo! Mr White"});

MessageProtocol Server/Client

Message protocol is implemented for wrapping all dynamic message types with a standard header.Please refer toMessage Protocolfor detailed explanation.

You can declare your payload types, which any type that is serializable with protobuf.

[ProtoContract]classSamplePayload:IProtoMessage{[ProtoMember(1)]publicstringsample;}

Example for the Secure Variant:

privatestaticasyncTaskExampleProtoSecure(){// null certificate or default constructor will generate self signed certificatevarscert=newX509Certificate2("server.pfx","greenpass");varcert=newX509Certificate2("client.pfx","greenpass");SecureProtoMessageServerserver=newSecureProtoMessageServer(20008,scert);server.StartServer();server.OnMessageReceived+=ServerMessageReceived;varclient=newSecureProtoMessageClient(cert);client.OnMessageReceived+=ClientMessageReceived;client.Connect("127.0.0.1",20008);varPayload=newSamplePayload(){sample="Hello"};varmessageEnvelope=newMessageEnvelope();messageEnvelope.Header="PayloadTest";// You can just send a message, get replies on ClientMessageReceived.client.SendAsyncMessage(messageEnvelope);client.SendAsyncMessage(messageEnvelope,Payload);// Or you can wait for a reply async.MessageEnveloperesult=awaitclient.SendMessageAndWaitResponse(messageEnvelope,Payload);varpayload=result.UnpackPayload<SamplePayload>();Console.WriteLine($"Client Got Response{payload.sample}");voidServerMessageReceived(GuidclientId,MessageEnvelopemessage){Console.WriteLine($"Server Received message{message.Header}");server.SendAsyncMessage(clientId,message);}voidClientMessageReceived(MessageEnvelopemessage){}}
  • Unsecure variantsProtoMessageServer andProtoMessageClient has identical signarures except the constructors doesnt take a ceritificate

Relay Server/Client and P2P

This model is what I personally use on my other projects such as P2PVideocall and Multiplayer Starfighter Game.Basically you have a Relay server somewhere in your network, which can act as a local network hub in LAN and/or open to connections from internet if port forwarding is enabled.
Relay clients (Peers) connect to Relay server and get notifications about existince of other peers. Peers can send messages to each other through Relay Server, or directly to each other (Udp holepunch).

Check outP2P Fore detailed info

Relay server

Server is completely passive, allowing other peers to discover and send messages to each other. Additionally NAT traversal methods such as UDP holepunching provided to allow direct communication via Internet or LAN (UDP only so far, but we have reliable udp).

Relay Server Is Serialization Agnostic which means any serialized network Peers, (Protobuff, MessagePack etc) can use the same relay server.
To use the Relay server, simply declere your server as:

varscert=newX509Certificate2("server.pfx","greenpass");varserver=newSecureProtoRelayServer(20010,scert);server.StartServer();

Relay server is already pre-configured.

Relay Client

Relay client is where your application logic is implemented. You can web your client applications to discover and talk with each other.
To declere a client:

// null certificate or default constructor will generate self signed certificatevarcert=newX509Certificate2("client.pfx","greenpass");varclient=newRelayClient(cert);client.OnPeerRegistered+=(GuidpeerId)=> ..client.OnPeerUnregistered+=(GuidpeerId)=> ..client.OnMessageReceived+=(MessageEnvelopemessage)=> ..client.OnUdpMessageReceived+=(MessageEnvelopemessage)=> ..client.OnDisconnected+=()=> ..client.Connect("127.0.0.1",20010);

Method signatures and callbacks are identical to proto client/server model (also with Payloads). Only difference is you have to specify the destination peer Guid Id. It comes from OnPeerRegistered event, whenever a new peer is connected to relay server. Relay Server guaranties syncronisation of current peer set with eventual consistency among all peers. So new peers will receive all other connected peers from this event and old peers will receive an update.

client.SendAsyncMessage(destinationPeerId,newMessageEnvelope(){Header="Hello"});client.SendUdpMesssage(destinationPeerId,newMessageEnvelope(){Header="Hello"});// Or with an async replyMessageEnveloperesponse=awaitclient.SendRequestAndWaitResponse(destinationPeerId,newMessageEnvelope(){Header="Who Are You?"});

Udp messages can be more than the datagram limit of 65,527 bytes. The system detects large udp messages as Jumbo messages and sends them in chunks. Receiving end with will try to reconstruct the message. if all the parts does not arrive within a timeout message is dropped.Max message size for udp is 16,256,000 bytes.

Reliable udp protocol uses as TCP algorithm implemented over UDP.

client.SendRudpMessage(peerId,envelope);client.SendRudpMessage(peerId,envelope,innerMessage);client.SendRudpMessageAndWaitResponse(peerId,envelope,innerMessage);client.SendRudpMessageAndWaitResponse(peerId,envelope);

Nat Traversal/Holepunch Support:

// Udpboolresult=awaitclient.RequestHolePunchAsync(destinationPeerId,timeOut:10000);// Tcpboolresult=awaitclient.RequestTcpHolePunchAsync(destinationPeerId,timeOut:10000);

if succesfull, it will allow you to send direct udp messages between current and destination peers for the rest of the udp messages in both directions.

Room/Lobby Server

This is an extention of Relay Server/Client. The addition is the room system where peers can create or join rooms, query available rooms, sends message to rooms(multicast).Additionally keeping same message system to send 1-1 messages among peers.

You can join multiple rooms

Room Server Is Serialization Agnostic which means any serialized network Peers, (Protobuf, MessagePack etc) can use the same Room server.

Decleration of Server and client

varserver=newSecureProtoRoomServer(20010,scert);server.StartServer();varclient1=newSecureProtoRoomClient(cert);

To create/join and leave rooms simply:

client1.CreateOrJoinRoom("Kitchen");client1.LeaveRoom("Kitchen");

Room callbacks are as followed. This callbacks are only triggered if you are in the same room.

client1.OnPeerJoinedRoom+=(roomName,peerId)=>..client1.OnPeerLeftRoom+=(roomName,peerId)=>..client1.OnPeerDisconnected+=(peerId)=>..

Additionally to the standard 1-1 message callback we have room message callbacks.

client1.OnTcpRoomMesssageReceived+=(roomName,message)=> ..client1.OnUdpRoomMesssageReceived+=(roomName,message)=> ..client1.OnTcpMessageReceived+=(message)=> ..client1.OnUdpMessageReceived+=(message)=> ..

P2P Remarks

  • Relay and lobby servers only uses MessageEnvelope and staticly serialized internal message types to communicate and provide functionalities, Therefore any Room client or Relay client, independent of what type of serialization they use, can acces and use all functionalities simultaneously.
  • Peers with different serialization protocols can talk with each other. They can send MessageEnvelope and Raw bytes without a problem. Understanding which protocol peer uses should be defined in application which is up to the user. Hence their serialized inner messages can be deserialized from envelope payload bytes accordingly.

Cyber Security

All secure TCP variants are implementing standard SSL socket with TLS authentication/validation.For more info check out :Security

About

High Performance Networking

Topics

Resources

License

Apache-2.0, Apache-2.0 licenses found

Licenses found

Apache-2.0
LICENSE
Apache-2.0
Licence.txt

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp