Awesome
<h1 align="center"><a href="https://github.com/alec1o/netly">Netly</a></h1> <h6 align="center"><sub> powered by <a href="https://github.com/alec1o">ALEC1O</a><sub/> </h6> <div align="center"> <img align="center" src="static/logo/netly-logo-3.png" width="128px" alt="netly logo"> </div>About
<br><sub> Netly is a powerful C# socket library that simplifies network communication. It supports HTTP, TCP, SSL/TLS, UDP, RUDP and WebSocket protocols, making it ideal for building multiplayer games, chat applications, and more.</sub>
Documentation
<br><sub>Netly docs (netly.docs.kezero.com)</sub>
Install
<sub>Official publisher</sub>
<sub>Nuget</sub> | <sub>Unity Asset Store</sub> |
---|---|
<sub>Install on Nuget</sub> | <sub>Install on Asset Store </sub> |
Supporter
</br>Why Contribute to Netly?
<sub><code>Solve Real-World Challenges</code> Netly simplifies socket programming, making it accessible for developers. By contributing, you’ll directly impact how games, chat applications, and real-time systems communicate.</br></sub>
<sub><code>Learn and Grow</code> Dive into the world of networking, encryption, and protocols. Gain practical experience by working on a versatile library used across platforms.</br></br></sub> <sub><code>Be Part of Something Bigger</code> Netly is open source, and your contributions will benefit the entire community. Join a passionate group of developers who believe in collaboration and knowledge sharing.</br></br></sub> <sub><code>Code, Ideas, and Feedback</code> Whether you’re a seasoned developer or just starting out, your code, ideas, and feedback matter. Every line of code, every suggestion, and every bug report contributes to Netly’s growth.</sub>
Sponsor
<div> <a href="https://www.jetbrains.com/community/opensource/"> <img alt="JetBrains sponsor notice" src="/static/JetBrains%20sponsor.png" width="400px" /> </a> </div> <br>Versions
<sub>Notable changes</sub>
<sub>v1 (old)</sub> | <sub>v2 (old)</sub> | <sub>v3 (stable)</sub> | <sub>v4 (In development)</sub> |
---|---|---|---|
<sub>TCP client server </sub> | <sub>TCP/IP Message Framing</sub> | <sub>TLS/SSL client server </sub> | <sub>WebSocket client server </sub> |
<sub>UDP client server </sub> | <sub>TCP/UDP performance increase </sub> | <sub>UDP connection from (ping/timeout) </sub> | <sub>HTTP client server </sub> |
<sub>Message Framing performance increase </sub> | <sub>TCP internal improvement <sub/> | ||
<sub>Message Framing new protocol </sub> | <sub>Documentation improvement </sub> | ||
<sub>Byter 2.0 </sub> | <sub>XML description improvement <sub> | ||
<sub>Collaborative documentation docsify </sub> |
List of tested platforms
<br>Feature
<sub>Below are some missing features that are planned to be added in later versions.</sub><br>
- <sub>
N/A
</sub>
Dependency
- <sub>Byter</sub>
Build
Build dependencies
Build step-by-step
# 1. clone project
$ git clone "https://github.com/alec1o/Netly" netly
# 2. build project
$ dotnet build "netly/" -c Release -o "netly/bin/"
# NOTE:
# Netly.dll require Byter.dll because is Netly dependency
# Netly.dll and Byter.dll have on build folder <netly-path>/bin/
<br>
Demo
<ul> <details> <summary><sub><strong>HTTP Client</strong></sub></summary>HTTP
using System;
using Netly;
var client = new HttpClient();
// error callback
client.OnError((exception) =>
{
// request exception error. when connection doesn't open, null uri,...
});
// success callback
client.OnSuccess((request) =>
{
// get status code
int statusCode = request.StatusCode;
// get server response as plain-text
string bodyAsPlainText = request.Body.PlainText;
});
// EXAMPLE:
// set header
client.Headers.Add("content-type", "multipart/form-data");
// set url query
client.Queries.Add("timeout", "1h");
// create form data
var body = new RequestBody(Enctype.Multipart);
// set filename.
body.Add("name", "Video.mp4");
// set filebuffer.
body.Add("file", new byte[]{ 1, 3, 4, 5, 6, 7, 8, 9, 0 });
// set request body.
client.Body = body;
// Don't block main thread, run on threadpolls.
// Send POST request.
client.Send("POST", new Uri("http://drive.kezero.com/upload?timeout=1h"));
</details>
<details>
<summary><sub><strong>HTTP Server</strong></sub></summary>
using System;
using Netly;
var server = new HttpServer();
server.OnOpen(() =>
{
// server started.
});
server.OnClose(() =>
{
// server closed.
});
server.OnError((exception) =>
{
// error on open server connection.
});
server.MapAll("/foo", (request, response) =>
{
// receives request from all http methods.
// EXAMPLE:
// Send response for client.
response.Send(200, $"Hello World. this http method is [{request.Method}]");
});
server.MapGet("/", (request, response) =>
{
// received GET request at "/" path.
});
server.MapPost("/login", (request, response) =>
{
// received POST request at "/login" path.
// EXAMPLE:
// request body on plain text.
string text = request.Body.PlainText;
// get email from http form.
string email = request.Body.Form.GetString("email");
// get password from http from.
string password = request.Body.Form.GetString("password");
// get uploaded file from http form. (<form method="post" enctype="multipart/form-data">).
byte[] picture = request.Body.Form.GetBytes("upload");
});
server.Open(new Uri("http://localhost:8080"));
</details>
</ul>
<br>
<ul> <details> <summary><sub><strong>Tcp Client</strong></sub></summary>TCP
using Netly;
using Netly.Core;
var client = new TcpClient(framing: true);
// Enable SSL/TLS (onValidate delegate is optional)
client.UseEncryption(enableEncryption: true, onValidate: null);
client.OnOpen(() =>
{
// client connected
});
client.OnClose(() =>
{
// client disconnected
});
client.OnError((Exception exception) =>
{
// connection close because: 1.Error on connecting, 2.Invalid framing data
});
client.OnData((byte[] data) =>
{
// raw data received
});
client.OnEvent((string name, byte[] data) =>
{
// event received (event use netly protocol)
});
client.OnModify((Socket socket) =>
{
// you can modify socket, called before open connection
});
client.Open(new Host("127.0.0.1", 8080));
</details>
<details>
<summary><sub><strong>Tcp Server</strong></sub></summary>
using Netly;
using Netly.Core;
var server = new TcpServer(framing: true);
// Enable SSL/TLS
byte[] pfxCert = <DO_SOMETHING>;
string pfxPass = <DO_SOMETHING>;
server.UseEncryption(pfxCert, pfxPass, SslProtocols.Tls13); // TLS v1.3
server.OnOpen(() =>
{
// server start listen
});
server.OnClose(() =>
{
// server stop listen
});
server.OnError((Exception exception) =>
{
// error on start listen (connecting)
});
server.OnData((TcpClient client, byte[] data) =>
{
// a client receive raw data
});
server.OnEvent((TcpClient client, string name, byte[] data) =>
{
// a client receive event (event use netly protocol)
});
server.OnEnter((TcpClient client) =>
{
// a client connected on server
client.OnClose(() =>
{
// alternative of: TcpServer.OnClose
});
client.OnData(() =>
{
// alternative of: TcpServer.OnData
});
client.OnEvent(() =>
{
// alternative of: TcpServer.OnEvent
});
});
server.OnExit((TcpClient client) =>
{
// a client disconnected from server
});
server.OnModify((Socket socket) =>
{
// you can modify socket, called before listen and bind a port
});
server.Open(new Host("127.0.0.1", 8080));
</details>
</ul>
<br>
<ul> <details> <summary><sub><strong>Udp Client</strong></sub></summary>UDP
using Netly;
using Netly.Core;
var client = new UdpClient(useConnection: true, timeout: 10000 /* 10s */);
client.OnOpen(() =>
{
// client connected
});
client.OnClose(() =>
{
// client disconnected
});
client.OnError((Exception exception) =>
{
// connection close because: 1.Error on connecting, 2.Invalid framing data
});
client.OnData((byte[] data) =>
{
// raw data received
});
client.OnEvent((string name, byte[] data) =>
{
// event received (event use netly protocol)
});
client.OnModify((Socket socket) =>
{
// you can modify socket, called before open connection
});
client.Open(new Host("127.0.0.1", 8080));
</details>
<details>
<summary><sub><strong>Udp Server</strong></sub></summary>
using Netly;
using Netly.Core;
var server = new UdpServer(useConnection: true, timeout: 15000 /* 15s */);
server.OnOpen(() =>
{
// server start listen
});
server.OnClose(() =>
{
// server stop listen
});
server.OnError((Exception exception) =>
{
// error on start listen (connecting)
});
server.OnData((UdpClient client, byte[] data) =>
{
// a client receive raw data
});
server.OnEvent((UdpClient client, string name, byte[] data) =>
{
// a client receive event (event use netly protocol)
});
server.OnEnter((UdpClient client) =>
{
// a client connected on server
client.OnClose(() =>
{
// alternative of: TcpServer.OnClose
});
client.OnData(() =>
{
// alternative of: TcpServer.OnData
});
client.OnEvent(() =>
{
// alternative of: TcpServer.OnEvent
});
});
server.OnExit((UdpClient client) =>
{
// a client disconnected from server
});
server.OnModify((Socket socket) =>
{
// you can modify socket, called before listen and bind a port
});
server.Open(new Host("127.0.0.1", 8080));
</details>
</ul>
<br>
<ul> <details> <summary><sub><strong>Websocket Client</strong></sub></summary>WebSocket
using System;
using Netly;
using Netly.Core;
var client = new WebsocketClient();
client.OnOpen(() =>
{
// websocket client connected.
});
client.OnClose(() =>
{
// websocket client disconnected.
});
client.OnError((exception) =>
{
// error on connect to server.
});
client.OnData((bytes, bufferType) =>
{
// websocket client received some data.
// EXAMPLE:
// send text data to server.
client.ToData("hello world!");
// send bynary data to server.
client.ToData(new byte[]{ 1, 2, 3 });
});
client.OnEvent((name, bytes, bufferType) =>
{
// websocket receives Netly event (Only Netly)
// EXAMPLE:
if (name == "client quit")
{
// send event to server
client.ToEvent("goodbye", "Some data here");
// close connection.
client.Close();
}
});
client.OnModify((ws) =>
{
// modify socket
});
// open connection.
client.Open(new Uri("ws://localhost:3000/"));
</details>
<details>
<summary><sub><strong>Websocket Server</strong></sub></summary>
using System;
using Netly;
var server = new HttpServer();
server.OnOpen(() =>
{
// server started.
});
server.OnClose(() =>
{
// server closed.
});
server.OnError((exception) =>
{
// error on open server connection.
});
// create websocket echo server.
server.MapWebsocket("/echo", (request, client) =>
{
client.OnData((bytes, bufferType) =>
{
// echo data.
client.ToData(bytes, bufferType);
});
client.OnEvent((name, bytes, bufferType) =>
{
// echo event.
client.ToEvent(name, bytes, bufferType);
});
});
// websocket server run on "/chat" route.
server.MapWebsocket("/chat", (request, client) =>
{
// websocket client connected.
// EXAMPLE:
// send data to client.
client.ToData("some data");
// send event to client.
client.ToEvent("hello_client", "some data");
// receive data
client.OnData((bytes, bufferType) =>
{
// websocket connected receive some data.
});
client.OnClose(() =>
{
// websocket client disconnected.
});
// receive event.
client.OnEvent((name, bytes, bufferType) =>
{
// websocket connected receive some event.
});
});
server.Open(new Uri("http://localhost:8080"));
</details>
</ul>
<br>