| TCP |
๐ Client
using Netly;
TCP.Client client = new TCP.Client(framing: true);
client.On.Open(() =>
{
printf("connection opened");
});
client.On.Close(() =>
{
printf("connetion closed");
});
client.On.Error((exception) =>
{
printf("connection erro on open");
});
client.On.Data((bytes) =>
{
printf("connection receive a raw data");
});
client.On.Event((name, data) =>
{
printf("connection receive a event");
});
client.On.Modify((socket) =>
{
printf("called before try open connection.");
});
client.On.Encryption((certificate, chain, errors) =>
{
// Only if client.IsEncrypted is enabled
printf("validate ssl/tls certificate");
// return true if certificate is valid
return true;
});
// open connection if closed
client.To.Open(new Host("127.0.0.1", 8080));
// close connection if opened
client.To.Close();
// send raw data if connected
client.To.Data(new byte[2] { 128, 255 });
client.To.Data("hello world", NE.Encoding.UTF8);
// send event if connected
client.To.Event("name", new byte[2] { 128, 255 });
client.To.Event("name", "hello world", NE.Encoding.UTF8);
// enable encryption (must call before client.To.Open)
client.To.Encryption(true);
๐ Server
using Netly;
TCP.Server server = new TCP.Server(framing: true);
server.On.Open(() =>
{
printf("connection opened");
});
server.On.Close(() =>
{
printf("connection closed");
});
server.On.Error((exception) =>
{
printf("connection error on open");
});
server.On.Accept((client) =>
{
client.On.Modify((socket) =>
{
printf("modify client socket e.g Enable NoDelay");
});
client.On.Open(() =>
{
printf("client connected");
});
client.On.Data((bytes) =>
{
printf("client receive a raw data");
});
client.On.Event((name, bytes) =>
{
printf("client receive a event");
});
client.On.Close(() =>
{
printf("client disconnected");
});
});
server.On.Modify((socket) =>
{
printf("called before try open connection.");
});
// open connection
server.To.Open(new Host("1.1.1.1", 1111));
// close connection
server.To.Close();
// enable encryption support (must called before server.To.Open)
server.To.Encryption(enable: true, @mypfx, @mypfxpassword, SslProtocols.Tls12);
// broadcast raw data for all connected client
server.To.DataBroadcast("text buffer");
server.To.DataBroadcast(new byte[] { 1, 2, 3 });
// broadcast event (netly event) for all connected client
server.To.EventBroadcast("event name", "text buffer");
server.To.EventBroadcast("event name", new byte[] { 1, 2, 3 });
|
|
|---|
| UDP |
๐ Client
using Netly;
UDP.Client client = new UDP.Client();
client.On.Open(() =>
{
printf("connection opened");
});
client.On.Close(() =>
{
printf("connection closed");
});
client.On.Error((exception) =>
{
printf("connection error on open");
});
client.On.Data((bytes) =>
{
printf("connection received a raw data");
});
client.On.Event((name, eventBytes) =>
{
printf("connection received a event");
});
client.On.Modify((socket) =>
{
printf("called before try open connection.");
});
// open connection if closed
client.To.Open(new Host("127.0.0.1", 8080));
// close connection if opened
client.To.Close();
// send raw data if connected
client.To.Data(new byte[2] { 128, 255 });
client.To.Data("hello world", NE.Encoding.UTF8);
// send event if connected
client.To.Event("name", new byte[2] { 128, 255 });
client.To.Event("name", "hello world", NE.Encoding.UTF8);
๐ Server
using Netly;
UDP.Server server = new UDP.Server();
server.On.Open(() =>
{
printf("connection opened");
});
server.On.Close(() =>
{
printf("connection closed");
});
server.On.Error((exception) =>
{
printf("connection error on open");
});
server.On.Accept((client) =>
{
client.On.Open(() =>
{
printf("client connected");
});
client.On.Close(() =>
{
// Only if use connection is enabled.
printf("client disconnected");
});
client.On.Data((bytes) =>
{
printf("client received a raw data");
});
client.On.Event((name, bytes) =>
{
printf("client received a event");
});
});
// open connection
server.To.Open(new Host("127.0.0.1", 8080));
// close connection
server.To.Close();
// broadcast raw data for all connected client
server.To.DataBroadcast("text buffer");
server.To.DataBroadcast(new byte[] { 1, 2, 3 });
// broadcast event (netly event) for all connected client
server.To.EventBroadcast("event name", "text buffer");
server.To.EventBroadcast("event name", new byte[] { 1, 2, 3 });
|
|
|---|
| HTTP |
๐ Client
using Netly;
HTTP.Client client = new HTTP.Client();
// add http header for request
client.Headers.Add("Content-Type", "json");
client.Headers.Add("Token", "ImGui.h");
// add http url queries e.g: https://www.alec1o.com/?page=about&version=4
client.Queries.Add("page", "about");
client.Queries.Add("version", "4");
// set request timeout (ms) default 15s (15000ms), 0 or negative value means infinite timeout.
client.Timeout = 6000; // 6s
// is opened: while is requesting
bool isFetching = client.IsOpened;
HttpClient http = null;
// called before try connect to server
// modify the HttpClient object
client.On.Modify((HttpClient instance) =>
{
http = instance;
});
// connection is opened and fetch server.
client.On.Open((response) =>
{
// you can use "http" instance on this scope (isn't null)
if (http.<foo> == <bar>) { ... }
});
// erro on fetch, it can be timeout or whatever error
// but if you receives error it mean the operation is called or done
client.On.Error((Exception exception) =>
{
Ny.Logger.PushError(exception);
});
// connection is closed with fetch server.
client.On.Close(() =>
{
if (http.<bar> == <foo>) { ... }
});
// used to fetch a server
client.To.Open("method e.g GET", "url", "body, allow null");
// used for cancel opened request
client.To.Close();
๐ Server
using Netly;
HTTP.Server server = new HTTP.Server();
// return true if server is serve http context
bool isServe = server.IsOpened;
server.On.Open(() =>
{
// http server opened
});
server.On.Close(() =>
{
// http server closed
});
server.On.Error((exception) =>
{
// http server open error
});
server.On.Modify((httpListener) =>
{
// HttpListener instance, called before try open connection.
});
// Open http server connection
server.To.Open(new Uri("http://127.0.0.1:8080/"));
// Close http server connection
server.To.Close();
// Map path
server.Map.Get("/", async (req, res) => {
// Handle async: GET
})
server.Map.Post("/user", (req, res) => {
// Handle sync: POST
});
// map using dynamic URL
server.Map.Delete("/post/{userId}/group/{groupId}", async (req, res)) =>
{
string userId = req.Param["userId"];
string groupId = req.Param["groupId"];
// Handle async: Delete from dynamic URL path
});
server.Map.WebSocket("/echo", (req, ws) =>
{
// Handle websocket connection from path
});
/*
You can map:
* Get # get request
* Post # post request
* Delete # delete request
* Put # put request
* Patch # patch request
* Trace # trace request
* Options # options request
* Head # head request, (only head)
* All # all http nethod request
* WebSocket # websocket request
*/
/*
Note: Middlewares is executed in added order.
BUT, LOCAL MIDDLEWARE HAVE PRIORITY THAN GLOBAL MIDDLEWARE
*/
// Global Middleware (*don't have workflow path)
server.Middleware.Add(async (req, res, next) => {
// verify request timer
Stopwatch watch = new Stopwatch(); // init timer
next(); // call another middleware.
watch.Stop(); // stop timer
res.Header.Add("Request-Timer", watch.ElapsedMilliseconds.ToString());
});
// Local middleware (have workflow path)
server.Middleware.Add("/admin", async (req, res, next) => {
if (MyApp.CheckAdminByHeader(req.Header))
{
res.Header.Add("Admin-Token", MyApp.RefreshAdminHeaderToken(req));
// call next middleware
next();
// now. all middleware is executed. (because this is two way middleware)
res.Header.Add("Request-Delay", (DateTime.UtcNow - timer)());
}
else
{
res.Header.Add("Content-Type", "application/json;charset=UTF-8");
await res.Send(404, "{ 'error': 'invalid request.' }");
// skip other middlewares:
// next();
}
});
// Register parse middleware
server.Middleware.Add((request, response, next) =>
{
if (request.Enctype == HTTP.Enctype.Json)
{
request.Body.RegisterParse(true, (Type type) =>
{
// e.g. using dotnet >= 6 @System.Text.Json
return JsonSerializer.Deserialize(request.Body.Text, type);
});
}
...
next();
});
// Usage of body parser.
server.Map.Post("/register", (request, response) =>
{
var data = request.Body.Parse<MyLoginInput>();
...
});
|
|
|---|
| RUDP |
๐ Client
using Netly;
RUDP.Client client = new RUDP.Client();
client.On.Open(() =>
{
printf("connection opened");
});
client.On.Close(() =>
{
printf("connection closed");
});
client.On.Error((exception) =>
{
printf("connection error on open");
});
client.On.Data((bytes, type) =>
{
printf("connection received a raw data");
});
client.On.Event((name, bytes, type) =>
{
printf("connection received a event");
});
client.On.Modify((socket) =>
{
printf("called before try open connection.");
});
// open connection if closed
client.To.Open(new Host("127.0.0.1", 8080));
// close connection if opened
client.To.Close();
// send raw data if connected
client.To.Data(new byte[2] { 128, 255 }, RUDP.Unreliable);
client.To.Data("hello world", NE.Encoding.UTF8, RUDP.Reliable);
// send event if connected
client.To.Event("name", new byte[2] { 128, 255 }, RUDP.Unreliable);
client.To.Event("name", "hello world", NE.Encoding.UTF8, RUDP.Reliable);
๐ Server
using Netly;
RUDP.Server server = new RUDP.Server();
server.On.Open(() =>
{
printf("connection opened");
});
server.On.Close(() =>
{
printf("connection closed");
});
server.On.Error((exception) =>
{
printf("connection error on open");
});
server.On.Accept((client) =>
{
client.On.Open(() =>
{
printf("client connected");
});
client.On.Close(() =>
{
// Only if use connection is enabled.
printf("client disconnected");
});
client.On.Data((bytes, type) =>
{
if (type == RUDP.Reliable) { ... }
else if (type == RUDP.Unreliable) { ... }
else { ... } /* type == RUDP.Sequenced */
printf("client received a raw data");
});
client.On.Event((name, type) =>
if (type == RUDP.Reliable) { ... }
else if (type == RUDP.Unreliable) { ... }
else { ... } /* type == RUDP.Sequenced */
printf("client received a event");
});
});
// open connection
server.To.Open(new Host("127.0.0.1", 8080));
// close connection
server.To.Close();
// broadcast raw data for all connected client
server.To.DataBroadcast("text buffer", RUDP.Unreliable);
server.To.DataBroadcast(new byte[] { 1, 2, 3 }, RUDP.Reliable);
server.To.DataBroadcast(new byte[] { 3, 2, 1 }, RUDP.Sequenced);
// broadcast event (netly event) for all connected client
server.To.EventBroadcast("event name", "text buffer", RUDP.Unreliable);
server.To.EventBroadcast("event name", new byte[] { 1, 2, 3 }, RUDP.Reliable);
server.To.EventBroadcast("event name", new byte[] { 3, 2, 1 }, RUDP.Sequenced);
|
|
|---|
| WebSocket |
๐ Client
using Netly;
HTTP.WebSocket client = new HTTP.WebSocket();
client.On.Open(() =>
{
// websocket connection opened
});
client.On.Close(() =>
{
// websocket connection closed
});
client.On.Error((exception) =>
{
// error on open websocket connectin
});
client.On.Data((bytes, type) =>
{
if (type == HTTP.Binary) { ... }
else if (type == HTTP.Text) { ... }
else { /* NOTE: it's imposible */ }
// raw data received from server
});
client.On.Event((name, bytes, type) =>
{
if (type == HTTP.Binary) { ... }
else if (type == HTTP.Text) { ... }
else { /* NOTE: it's imposible */ }
// event received from server
});
client.On.Modify((wsSocket) =>
{
// modify websocket socket
});
// open websocket client connection
client.To.Open(new Uri("ws://127.0.0.1:8080/echo"));
// close websocket client connection
client.To.Close();
// send raw data for server
// text message
client.To.Data("my message", HTTP.Text);
// binnary message
client.To.Data(NE.GetBytes("my buffer"), HTTP.Binary);
// send event (netly event) for server
// text message
client.To.Event("event name", "my message", HTTP.Text);
// binnary message
client.To.Data("event name", NE.GetBytes("my buffer"), HTTP.Binary);
๐ Server
using Netly;
using Netly.Interfaces;
HTTP.Server server = new HTTP.Server();
IHTTP.WebSocket[] Clients = server.WebSocketClients;
server.Map.WebSocket("/chat/{token}", async (req, ws) =>
{
// Accept websocket from dynamic path
string token = req.Params["token"];
// validate websocket connection from params
if (Foo.Bar(token) == false)
{
ws.To.Close();
}
ws.On.Modify(...);
ws.On.Open(...);
ws.On.Close(...);
ws.On.Data(...);
ws.On.Event(...);
});
server.Map.Websocket("/echo", (req, ws) =>
{
// Handle websocket on /echo path
ws.On.Modify((wsSocket) =>
{
// modify server-side websocket ocket
});
ws.On.Open(() =>
{
// server-side websocket connection opened
});
ws.On.Close(() =>
{
// server-side websocket connection closed
});
ws.On.Data((bytes, type) =>
{
if (type == HTTP.Binary) { ... }
else if (type == HTTP.Text) { ... }
else { /* NOTE: it's imposible */ }
// server-side websocket received raw data
});
ws.On.Event((name, bytes, type) =>
{
if (type == HTTP.Binary) { ... }
else if (type == HTTP.Text) { ... }
else { /* NOTE: it's imposible */ }
// server-side websocket received event
});
});
server.On.Open(() =>
{
// http server opened
});
server.On.Close(() =>
{
// http server closed
});
server.On.Error((exception) =>
{
// http server open error
});
server.On.Modify((httpListener) =>
{
// HttpListener instance, called before try open connection.
});
// Open http server connection
server.To.Open(new Uri("http://127.0.0.1:8080/"));
// Close http server connection
server.To.Close();
// open websocket client connection
client.To.Open(new Uri("ws://127.0.0.1:8080/echo"));
// close websocket client connection
client.To.Close();
// broadcast raw data for all connected websocket socket
// text message
server.To.WebsocketDataBroadcast("my message", HTTP.Text);
// binnary message
server.To.WebsocketDataBroadcast(NE.GetBytes("my buffer"), HTTP.Binary);
// broadcast event (netly event) for all connected websocket socket
// text message
server.To.WebsocketEventBroadcast("event name", "my message", HTTP.Text);
// binnary message
server.To.WebsocketEventBroadcast("event name", NE.GetBytes("my buffer"), HTTP.Binary);
|
|
|---|
| Byter |
Byter documentation: alec1o/Byter
๐ Primitive
using Byter;
-
Serialize (have +20 types of data supported, e.g. enum, bool, array, list, class,
struct,... see official docs
Primitive primitive = new();
// add element
primitive.Add.ULong(1024); // e.g. Id
primitive.Add.DateTime(DateTime.UtcNow); // e.g. Sent Time
primitive.Add.Struct(new Student() {...}); // e.g Student
primitive.Add.Class(new Employee() {...}); // e.g Employee
...
// get buffer
byte[] buffer = primitive.GetBytes();
-
Deserialize
// WARNING: Need primitive buffer to deserialize
Primitive primitive = new(...buffer);
ulong id = primitive.Get.ULong();
DateTime sentTime = primitive.Get.DateTime();
Student student = primitive.Get.Struct<Student>();
Employee employee = primitive.Get.Class<Employee>();
/*
* NOTE: Primitive don't make exception when diserialize error,
* don't need try/catch block
*/
if (primitive.IsValid is false)
{
// discart this. +1/all failed on deserialize
return;
}
// deserialized sucessful
-
*Dynamic Read Technical
Primitive primitive = new(...buffer);
var topic = primitive.Get.Enum<Topic>();
if(!primitive.IsValid) return; // discart this, topic not found.
switch(topic)
{
case Topic.Student:
{
// read student info e.g.
var student = primitive.Get.Struct<Student>();
...
return;
}
case Topic.Employee:
{
// read employee info e.g.
var employee = primitive.Get.Class<Employee>();
...
return;
}
default:
{
// discart this, topic not found.
...
return;
}
}
Primitive can serialize/deserialize complex data, e.g. (T[], List, Class, Struct, Enum).
But when you want to deserialize your (Class, Structure, List<Class/Struct>, Class/Struct[]), It must have:
-
(generic and public constructor: is a public constructor with no arguments, e.g. which allows:
Human human = new Human();
-
And the class/struct property must have public access and { get; set; } or not private
for example. (In byter programming, ONLY PROPERTIES THAT CAN BE READ AND WRITTEN WILL BE SERIALIZED AND DESERIALIZED)
// valid
public string Name;
public string Name { get; set; }
internal string Name; // !!! if visible from Byter
internal string Name { get; set; }; // !!! if visible from Byter
// invalid
private string Name;
private string Name { get; set; }
internal string Name; // !!! if unvisible from Byter
internal string Name { get; set; }; // !!! if unvisible from Byter
๐ Extension
using Byter;
-
Global Default
Encoding (source code spec)
// update global defaut encoding. Default is UTF8
StringExtension.Default = Encoding.Unicode; // Unicode is UTF16
-
Convert string to byte[]
// using global encoding (*UTF8)
byte[] username = "@alec1o".GetBytes();
// using UNICODE (*UTF16) encoding
byte[] message = "Hello ๐ World ๐".GetBytes(Encoding.Unicode);
// using UTF32 encoding
string secreatWord = "I'm not human, I'm a concept.";
byte[] secreat = secreatWord.GetBytes(Encoding.UTF32);
-
Convert byte[] to string
// using global encoding (*UTF8)
string username = new byte[] { ... }.GetString();
// using UNICODE (*UTF16) encoding
string message = new byte[] { ... }.GetString(Encoding.Unicode);
// using UTF32 encoding
byte[] secreat = new byte[] { ... };
string secreatWord = secreat.GetString(Encoding.UTF32);
-
Capitalize string
string name = "alECio furanZE".ToCapitalize();
# Alecio Furanze
string title = "i'M noT humAn";
title = title.ToCapitalize();
# I'm Not Human
-
UpperCase string
string name = "alECio furanZE".ToUpperCase();
# ALECIO FURANZE
string title = "i'M noT humAn";
title = title.ToUpperCase();
# I'M NOT HUMAN
-
LowerCase string
string name = "ALEciO FUraNZE".ToLowerCase();
# alecio furanze
string title = "i'M Not huMAN";
title = title.ToLowerCase();
# i'm not human

|