Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
71 changed files
with
33,239 additions
and
7 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
**NetPacketProcessor** - fast specialized for network purposes serializer.<br> | ||
It supports **classes** with **public properties with "get" and "set"** methods or **classes/structs with implemented `INetSerializable`**.<br> | ||
Serializer adds some overhead in size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet. | ||
### Supported property types | ||
```csharp | ||
byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint | ||
byte[] short[] ushort[] int[] uint[] long[] ulong[] float[] double[] bool[] string[] | ||
``` | ||
### Serialization speed comparsion | ||
Serialization 100_000 times of simple structure from [example](https://github.com/RevenantX/LiteNetLib/blob/master/LibSample/SerializerBenchmark.cs): | ||
``` | ||
BinaryFormatter time: 3418 ms | ||
NetSerializer first run time: 127 ms | ||
NetSerializer second run time: 99 ms | ||
DataWriter (raw put method calls) time: 24 ms | ||
``` | ||
### Packet Example | ||
```csharp | ||
class SamplePacket | ||
{ | ||
public string SomeString { get; set; } | ||
public float SomeFloat { get; set; } | ||
public int[] SomeIntArray { get; set; } | ||
} | ||
``` | ||
### Nested structs or classes | ||
It does not supports nested structs or classes.<br> | ||
But you can register custom type processor.<br> | ||
That usefull for game engine types such as Vector3 and Quaternion (in Unity3d). | ||
```csharp | ||
//Your packet that will be sent over network | ||
class SamplePacket | ||
{ | ||
public MyType SomeMyType { get; set; } | ||
|
||
//Arrays of custom types supported too | ||
public MyType[] SomeMyTypes { get; set; } | ||
} | ||
|
||
//Some custom type (variant 1) | ||
struct MyType | ||
{ | ||
public int Value1; | ||
public string Value2; | ||
|
||
public static void Serialize(NetDataWriter writer, SomeMyType mytype) | ||
{ | ||
writer.Put(mytype.Value1); | ||
writer.Put(mytype.Value2); | ||
} | ||
|
||
public static MyType Deserialize(NetDataReader reader) | ||
{ | ||
MyType res = new MyType(); | ||
res.Value1 = reader.GetInt(); | ||
res.Value2 = reader.GetString(); | ||
return res; | ||
} | ||
} | ||
... | ||
netPacketProcessor = new NetPacketProcessor(); | ||
netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); | ||
``` | ||
Another variant you can implement INetSerializable interface: | ||
```csharp | ||
//Some custom type (variant 2) | ||
struct SomeMyType : INetSerializable | ||
{ | ||
public int Value1; | ||
public string Value2; | ||
|
||
public void Serialize(NetDataWriter writer) | ||
{ | ||
writer.Put(Value1); | ||
writer.Put(Value2); | ||
} | ||
|
||
public void Deserialize(NetDataReader reader) | ||
{ | ||
Value1 = reader.GetInt(); | ||
Value2 = reader.GetString(); | ||
} | ||
} | ||
... | ||
netPacketProcessor = new NetPacketProcessor(); | ||
netPacketProcessor.RegisterNestedType<SomeMyType>(); | ||
``` | ||
Or if you want use struct instead of class (and implement INetSerializable interface) | ||
you must provide constructor: | ||
```csharp | ||
netPacketProcessor.RegisterNestedType<SomeMyType>(() => { return new SomeMyType(); }); | ||
``` | ||
# Usage example (for full example look at source [SerializerBenchmark](https://github.com/RevenantX/LiteNetLib/blob/master/LibSample/SerializerBenchmark.cs)) | ||
```csharp | ||
//First side | ||
class SomeClientListener : INetEventListener | ||
{ | ||
private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); | ||
... | ||
public void OnPeerConnected(NetPeer peer) | ||
{ | ||
SamplePacket sp = new SamplePacket | ||
{ | ||
SomeFloat = 3.42f, | ||
SomeIntArray = new[] {6, 5, 4}, | ||
SomeString = "Test String", | ||
} | ||
peer.Send(_netPacketProcessor.Write(sp), DeliveryMethod.ReliableOrdered); | ||
//or you can use _netPacketProcessor.Send(peer, sp, DeliveryMethod.ReliableOrdered); | ||
} | ||
} | ||
|
||
//Other side | ||
class SomeServerListener : INetEventListener | ||
{ | ||
private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); | ||
|
||
public SomeServerListener() | ||
{ | ||
//Subscribe to packet receiving | ||
_netPacketProcessor.SubscribeReusable<SamplePacket, NetPeer>(OnSamplePacketReceived); | ||
} | ||
|
||
private void OnSamplePacketReceived(SamplePacket samplePacket, NetPeer peer) | ||
{ | ||
Console.WriteLine("[Server] ReceivedPacket:\n" + samplePacket.SomeString); | ||
} | ||
|
||
public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) | ||
{ | ||
Console.WriteLine("[Server] received data. Processing..."); | ||
_netPacketProcessor.ReadAllPackets(reader, peer); | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
- name: Introduction | ||
href: intro.md | ||
- name: NetSerializer usage | ||
href: netserializerusage.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,141 @@ | ||
# This is the **HOMEPAGE**. | ||
Refer to [Markdown](http://daringfireball.net/projects/markdown/) for how to write markdown files. | ||
## Quick Start Notes: | ||
1. Add images to the *images* folder if the file is referencing an image. | ||
# LiteNetLib | ||
|
||
Lite reliable UDP library for .NET Framework 3.5, Mono, .NET Core 2.0, .NET Standard 2.0. | ||
|
||
[![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) | ||
|
||
[Little Game Example on Unity](https://github.com/RevenantX/NetGameExample) | ||
|
||
## Features | ||
|
||
* Lightweight | ||
* Small CPU and RAM usage | ||
* Small packet size overhead ( 1 byte for unreliable, 3 bytes for reliable packets ) | ||
* Simple connection handling | ||
* Peer to peer connections | ||
* Helper classes for sending and reading messages | ||
* Multiple data channels | ||
* Different send mechanics | ||
* Reliable with order | ||
* Reliable without order | ||
* Reliable sequenced (realiable only last packet) | ||
* Ordered but unreliable with duplication prevention | ||
* Simple UDP packets without order and reliability | ||
* Fast packet serializer [(Usage manual)](https://github.com/RevenantX/LiteNetLib/wiki/NetSerializer-usage) | ||
* Automatic small packets merging | ||
* Automatic fragmentation of reliable packets | ||
* Automatic MTU detection | ||
* UDP NAT hole punching | ||
* NTP time requests | ||
* Packet loss and latency simulation | ||
* IPv6 support (dual mode) | ||
* Connection statisitcs (need DEBUG or STATS_ENABLED flag) | ||
* Multicasting (for discovering hosts in local network) | ||
* Unity support | ||
* Supported platforms: | ||
* Windows/Mac/Linux (.NET Framework, Mono, .NET Core) | ||
* Android (Unity) | ||
* iOS (Unity) | ||
* UWP Windows 10 including phones | ||
* Lumin OS (Magic Leap) | ||
|
||
## Unity notes!!! | ||
* Always use library sources instead of precompiled DLL files ( because there are platform specific #ifdefs and workarounds for unity bugs ) | ||
|
||
## Usage samples | ||
|
||
### Client | ||
```csharp | ||
EventBasedNetListener listener = new EventBasedNetListener(); | ||
NetManager client = new NetManager(listener); | ||
client.Start(); | ||
client.Connect("localhost" /* host ip or name */, 9050 /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); | ||
listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod) => | ||
{ | ||
Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); | ||
dataReader.Recycle(); | ||
}; | ||
|
||
while (!Console.KeyAvailable) | ||
{ | ||
client.PollEvents(); | ||
Thread.Sleep(15); | ||
} | ||
|
||
client.Stop(); | ||
``` | ||
### Server | ||
```csharp | ||
EventBasedNetListener listener = new EventBasedNetListener(); | ||
NetManager server = new NetManager(listener); | ||
server.Start(9050 /* port */); | ||
|
||
listener.ConnectionRequestEvent += request => | ||
{ | ||
if(server.PeersCount < 10 /* max connections */) | ||
request.AcceptIfKey("SomeConnectionKey"); | ||
else | ||
request.Reject(); | ||
}; | ||
|
||
listener.PeerConnectedEvent += peer => | ||
{ | ||
Console.WriteLine("We got connection: {0}", peer.EndPoint); // Show peer ip | ||
NetDataWriter writer = new NetDataWriter(); // Create writer class | ||
writer.Put("Hello client!"); // Put some string | ||
peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability | ||
}; | ||
|
||
while (!Console.KeyAvailable) | ||
{ | ||
server.PollEvents(); | ||
Thread.Sleep(15); | ||
} | ||
server.Stop(); | ||
``` | ||
|
||
## NetManager settings description | ||
|
||
* **UnconnectedMessagesEnabled** | ||
* enable messages receiving without connection. (with SendUnconnectedMessage method) | ||
* default value: **false** | ||
* **NatPunchEnabled** | ||
* enable NAT punch messages | ||
* default value: **false** | ||
* **UpdateTime** | ||
* library logic update (and send) period in milliseconds | ||
* default value: **15 msec**. | ||
* **PingInterval** | ||
* Interval for latency detection and checking connection | ||
* default value: **1000 msec**. | ||
* **DisconnectTimeout** | ||
* if client or server doesn't receive any packet from remote peer during this time then connection will be closed | ||
* (including library internal keepalive packets) | ||
* default value: **5000 msec**. | ||
* **SimulatePacketLoss** | ||
* simulate packet loss by dropping random amout of packets. (Works only in DEBUG mode) | ||
* default value: **false** | ||
* **SimulateLatency** | ||
* simulate latency by holding packets for random time. (Works only in DEBUG mode) | ||
* default value: **false** | ||
* **SimulationPacketLossChance** | ||
* chance of packet loss when simulation enabled. value in percents. | ||
* default value: **10 (%)** | ||
* **SimulationMinLatency** | ||
* minimum simulated latency | ||
* default value: **30 msec** | ||
* **SimulationMaxLatency** | ||
* maximum simulated latency | ||
* default value: **100 msec** | ||
* **BroadcastEnabled** | ||
* Allows receive Broadcast packets | ||
* default value: **false** | ||
* **ReconnectDelay** | ||
* delay betwen connection attempts | ||
* default value: **500 msec** | ||
* **MaxConnectAttempts** | ||
* maximum connection attempts before client stops and call disconnect event. | ||
* default value: **10** | ||
* **UnsyncedEvents** | ||
* Experimental feature. Events automatically will be called without PollEvents method from another thread | ||
* default value: **false** |
Oops, something went wrong.