{"id":20003162,"url":"https://github.com/alec1o/netly","last_synced_at":"2025-05-04T15:34:42.247Z","repository":{"id":58852963,"uuid":"532754407","full_name":"alec1o/Netly","owner":"alec1o","description":"Netly: Cross-Platform, Multi-Protocol C# Socket Library – Fast, Easy, and Versatile.⚡","archived":false,"fork":false,"pushed_at":"2025-04-28T16:50:17.000Z","size":7525,"stargazers_count":72,"open_issues_count":5,"forks_count":12,"subscribers_count":5,"default_branch":"dev","last_synced_at":"2025-04-28T17:32:43.084Z","etag":null,"topics":["alec1o","c-sharp","chat","dotnet","http","mono","multiplayer","net","netly","network","networking","realtime","rudp","socket","sockets","ssl","tcp","tls","udp","websocket"],"latest_commit_sha":null,"homepage":"https://netly.docs.kezero.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alec1o.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-05T05:22:04.000Z","updated_at":"2025-04-28T16:22:04.000Z","dependencies_parsed_at":"2023-09-28T23:55:03.187Z","dependency_job_id":"74f2b18a-b68b-4fee-b0b5-2bedb9596c66","html_url":"https://github.com/alec1o/Netly","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alec1o%2FNetly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alec1o%2FNetly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alec1o%2FNetly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alec1o%2FNetly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alec1o","download_url":"https://codeload.github.com/alec1o/Netly/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252357242,"owners_count":21735104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alec1o","c-sharp","chat","dotnet","http","mono","multiplayer","net","netly","network","networking","realtime","rudp","socket","sockets","ssl","tcp","tls","udp","websocket"],"created_at":"2024-11-13T05:24:28.637Z","updated_at":"2025-05-04T15:34:42.196Z","avatar_url":"https://github.com/alec1o.png","language":"C#","readme":"\u003e ###### Active development occurs on the [_'dev'_](https://github.com/alec1o/Netly/tree/dev) branch. For the stable release, refer to the [_'main'_](https://github.com/alec1o/Netly/tree/main) branch.\n\n\u003csup\u003eNetly version 4 is now available! Experience the new way of interacting with Netly. [_See more_](https://github.com/alec1o/Netly/discussions/36#discussion-6204441)\u003csup\u003e\n\n\u003cdiv align=\"right\"\u003e\n  \u003ctable\u003e\n    \u003ctd align=\"left\"\u003e\n      \u003cp\u003e\n        \u003csup\u003e⭐ Your star on \u003ca href=\"https://github.com/alec1o/Netly\"\u003eNetly\u003c/a\u003e brightens our journey and makes a real impact!\u003cbr\u003e ✨ Every like/star is a powerful boost that drives us forward.\u003cbr\u003e 💙 Thank you for your incredible support!\n\u003c/sup\u003e\n      \u003c/p\u003e\n    \u003c/td\u003e\n  \u003c/table\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n\u003ch1 align=\"center\"\u003e\u003ca href=\"https://github.com/alec1o/Netly\"\u003eNetly\u003c/a\u003e\u003c/h1\u003e\n\n\u003ch6 align=\"center\"\u003e\u003csub\u003e\npowered by \u003ca href=\"https://github.com/alec1o\"\u003eALEC1O\u003c/a\u003e\u003csub/\u003e\n\u003c/h6\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"#\"\u003e\n    \u003cimg align=\"center\" src=\"static/logo/netly-logo-3.png\" width=\"128px\" alt=\"netly logo\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n##### Project\n\n\u003e \u003csub\u003eGet basic information about this project called [Netly](https://github.com/alec1o/Netly)\u003c/sub\u003e\n\n\u003ctable\u003e\n    \u003ctr\u003e\n      \u003cth align=\"center\" valign=\"center\"\u003e\u003csub\u003e\u003cstrong\u003eOverview\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cbr\u003e\n\u003csub\u003eNetly is a robust C# socket library designed to streamline network communication. It offers comprehensive support for multiple protocols, including HTTP, TCP, SSL/TLS, UDP, Reliable UDP (RUDP), and WebSocket. This versatility makes Netly an excellent choice for developing a wide range of applications, from multiplayer games and chat systems to real-time data exchanges.\u003c/sub\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth align=\"center\" valign=\"center\"\u003e\u003csub\u003e\u003cstrong\u003eWebsite\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cbr\u003e\n\u003csub\u003eRepository: \u003ca href=\"https://github.com/alec1o/Netly\"\u003e\u003ci\u003egithub.com/alec1o/netly\u003c/i\u003e\u003c/a\u003e\u003c/sub\u003e\n\u003cbr\u003e\n\u003csub\u003eDocumentation: \u003ca href=\"https://netly.docs.kezero.com\"\u003e\u003ci\u003enetly.docs.kezero.com\u003c/i\u003e\u003c/a\u003e\u003c/sub\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth align=\"center\" valign=\"center\"\u003e\u003csub\u003e\u003cstrong\u003eSponsor\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cbr\u003e\n\u003cdiv\u003e\n    \u003ca href=\"https://www.buymeacoffee.com/alec1o\"\u003e\n      \u003cimg src=\"https://img.buymeacoffee.com/button-api/?text=Buy me a coffee\u0026emoji=☕\u0026slug=alec1o\u0026button_colour=FFDD00\u0026font_colour=000000\u0026font_family=Cookie\u0026outline_colour=000000\u0026coffee_colour=ffffff\" /\u003e\u0026nbsp;\u0026nbsp;\n      \u003csup\u003eKeep Netly alive – sponsor it on Buy Me a Coffee.\u003c/sup\u003e\n    \u003c/a\u003e\n    \u003cbr\u003e\u003chr\u003e\n    \u003ca href=\"https://www.kezero.com/?invite=netly\" justify=\"start\" align=\"start\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/kezerocom/BrandAsset/refs/heads/main/logo/v2/blue.png\" alt=\"KeZero logo.\" height=\"45px\"\u003e\u0026nbsp;\u0026nbsp;\n        \u003csup\u003eKeZero sponsor Netly with hosting infrastructure and website domain.\u003c/sup\u003e\n    \u003c/a\u003e\u003chr\u003e\n    \u003ca href=\"https://www.jetbrains.com/community/opensource/\"\u003e\n        \u003cimg src=\"https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.png\" alt=\"JetBrains logo.\" height=\"30px\"\u003e\u0026nbsp;\u0026nbsp;\n        \u003csup\u003eNetly receives JetBrains' IDE for free, Thanks to their generous  sponsorship.\u003c/sup\u003e\n    \u003c/a\u003e\u003cbr\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003cth align=\"center\" valign=\"center\"\u003e\u003csup\u003e\u003cstrong\u003eSupporter\u003c/strong\u003e\u003c/sup\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003ch6\u003eWhy Contribute to Netly?\u003c/h6\u003e\n\n-   \u003csub\u003e\u003cstrong\u003eTransform Network Communication:\u003c/strong\u003e \u003cbr\u003eJoin us in revolutionizing how software communicates. Your contributions will help build a library that sets new standards for efficiency and reliability.\u003c/sub\u003e\n-   \u003csub\u003e\u003cstrong\u003eAdvance Your Career:\u003c/strong\u003e \u003cbr\u003eEngage with innovative projects, solve complex problems, and collaborate with experts. Your involvement will sharpen your skills and expand your professional network.\u003c/sub\u003e\n-   \u003csub\u003e\u003cstrong\u003eShare Your Ideas:\u003c/strong\u003e \u003cbr\u003eWhether you're a seasoned developer or just starting out, your ideas are valuable. Contribute thoughts and suggestions to shape the future of Netly and drive innovation.\u003c/sub\u003e\n\n\u003cbr\u003e\n\n\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n##### Installing\n\n\u003e \u003csub\u003eOfficial publisher\u003c/sub\u003e\n\n| \u003csub\u003eNuget\u003c/sub\u003e                                                    | \u003csub\u003eUnity Asset Store\u003c/sub\u003e                                                                     |\n| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |\n| \u003csub\u003eInstall on [Nuget](https://www.nuget.org/packages/Netly)\u003c/sub\u003e | \u003csub\u003eInstall on [Asset Store ](https://assetstore.unity.com/packages/tools/network/225473)\u003c/sub\u003e |\n\n\u003cbr\u003e\n\n##### Versions\n\n\u003e \u003csub\u003eNotable changes\u003c/sub\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e \u003c!-- title --\u003e\n\u003cth\u003e\u003csub\u003ev1.x.x\u003c/sub\u003e\u003c/th\u003e\n\u003cth\u003e\u003csub\u003ev2.x.x\u003c/sub\u003e\u003c/th\u003e\n\u003cth\u003e\u003csub\u003ev3.x.x\u003c/sub\u003e\u003c/th\u003e\n\u003cth\u003e\u003csub\u003ev4.x.x\u003c/sub\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- status --\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\u003csup\u003e\u003csub\u003e\u003ci\u003eLegacy\u003c/i\u003e\u003c/sub\u003e\u003c/sup\u003e\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\u003csup\u003e\u003csub\u003e\u003ci\u003eLegacy\u003c/i\u003e\u003c/sub\u003e\u003c/sup\u003e\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\u003csup\u003e\u003csub\u003e\u003ci\u003eStable\u003c/i\u003e\u003c/sub\u003e\u003c/sup\u003e\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\u003csup\u003e\u003csub\u003e\u003ci\u003eLatest\u003c/i\u003e\u003c/sub\u003e\u003c/sup\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #1 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eTCP Support\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eTCP with \u003ca href=\"https://bit.ly/message-framing\"\u003eMessage Framing support\u003c/a\u003e\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eTCP with TLS/SSL support\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eHTTP client and server support\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #2 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eUDP Support\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eTCP and UDP performance increase\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eUDP with connection (timeout response)\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eReliable UDP (RUDP) client and server support\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #3 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eNew \u003ca href=\"https://bit.ly/message-framing\"\u003eMessage Framing\u003c/a\u003e protocol and performance increase\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eWebSocket client and server support\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #4 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eUpgrade to \u003ca href=\"https://github.com/alec1o/Byter\"\u003eByter 2.0\u003c/a\u003e\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eUpgrade to \u003ca href=\"https://github.com/alec1o/Byter\"\u003eByter 4.0\u003c/a\u003e\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #4 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003e\u003ca href=\"https://github.com/docsifyjs/docsify\"\u003eDocsify\u003c/a\u003e as documentation framework\u003c/sub\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eDocumentation improvement by \u003ca href=\"https://github.com/facebook/docusaurus\"\u003eDocusaurus\u003c/a\u003e and \u003ca href=\"https://github.com/Jan0660/DocFxMarkdownGen\"\u003eDocFxMarkdownGen\u003c/a\u003e\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #5 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eSyntax and internal improvement\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e \u003c!-- row #6 --\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003c/td\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\u003csub\u003eXML comments improvement\u003c/sub\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n##### Integrations\n\n\u003e \u003csub\u003eTechnical descriptions about integrations\u003c/sub\u003e\n\n\u003ctable\u003e\n    \u003ctr valign=\"top\" align=\"left\"\u003e\n        \u003cth\u003e\u003csub\u003eList of tested platforms\u003c/sub\u003e\u003c/th\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\n\u003cbr\u003e\n\n-   \u003csub\u003e[.NET](https://dotnet.microsoft.com) (SDK)\u003c/sub\u003e\n-   \u003csub\u003e[Mono](https://mono-project.com) (SDK)\u003c/sub\u003e\n-   \u003csub\u003e[Unity](https://unity.com) (Engine)\u003c/sub\u003e\n-   \u003csub\u003e[Operating system](https://en.wikipedia.org/wiki/Operating_system) (OS)\u003c/sub\u003e\n    - \u003csub\u003eAndroid\u003c/sub\u003e\n    - \u003csub\u003eiOS\u003c/sub\u003e\n    - \u003csub\u003eWindows\u003c/sub\u003e\n    - \u003csub\u003eLinux\u003c/sub\u003e\n    - \u003csub\u003emacOS\u003c/sub\u003e\u003cbr\u003e\u003cbr\u003e\n    \u003csub\u003e\u003cstrong\u003eNotice\u003c/strong\u003e: \u003ci\u003eThis library might run on all devices. If it doesn't work on any device, it\n    should be considered a bug and reported.\u003ci\u003e\u003csub\u003e\n\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr valign=\"top\" align=\"left\"\u003e\n        \u003cth\u003e\u003csub\u003eDependencies\u003c/sub\u003e\u003c/th\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\n\u003cbr\u003e\n\u003ca href=\"https://github.com/alec1o/Byter\"\u003e\u003cimg alt=\"byter logo\" src=\"static/Byter-logo-512/sprite_1.png\" width=\"24px\"\u003e \u003csup\u003e\u003cstrong\u003e\nByter\u003c/strong\u003e\u003c/sup\u003e\u003c/a\u003e\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr valign=\"top\" align=\"left\"\u003e\n        \u003cth\u003e\u003csub\u003eBuild\u003c/sub\u003e\u003c/th\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\n\u003cbr\u003e\n\n\u003e ###### Build dependencies\n\n-   \u003csub\u003e[Git](http://git-scm.com/)\u003c/sub\u003e\n-   \u003csub\u003e[.NET](http://dot.net)\u003c/sub\u003e\n\n\u003e ###### Build step-by-step\n\n```rb\n# 1. clone project\n$ git clone \"https://github.com/alec1o/Netly\" netly\n\n# 2. build project\n$ dotnet build \"netly/\" -c Release -o \"netly/bin/\"\n\n# NOTE:\n# Netly.dll require Byter.dll because is Netly dependency\n# Netly.dll and Byter.dll have on build folder \u003cnetly-path\u003e/bin/\n```\n\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr valign=\"top\" align=\"left\"\u003e\n        \u003cth\u003e\u003csub\u003eFeatures\u003c/sub\u003e\u003c/th\u003e\n\u003ctd valign=\"top\" align=\"left\"\u003e\n\u003cbr\u003e\n\n\u003e \u003csub\u003eBelow are some missing features that are planned to be added in later versions.\u003c/sub\u003e\u003cbr\u003e\n\n-   \u003csub\u003e`N/A`\u003c/sub\u003e\n\n\u003cbr\u003e\n\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n##### Examples\n\n\u003e \u003csub\u003eCode highlights\u003c/sub\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003eTCP\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd width=\"100%\"\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eClient\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nTCP.Client client = new TCP.Client(framing: true);\n```\n\n```csharp\nclient.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nclient.On.Close(() =\u003e\n{\n    printf(\"connetion closed\");\n});\n\nclient.On.Error((exception) =\u003e\n{\n    printf(\"connection erro on open\");\n});\n\nclient.On.Data((bytes) =\u003e\n{\n    printf(\"connection receive a raw data\");\n});\n\nclient.On.Event((name, data) =\u003e\n{\n    printf(\"connection receive a event\");\n});\n\nclient.On.Modify((socket) =\u003e\n{\n    printf(\"called before try open connection.\");\n});\n\nclient.On.Encryption((certificate, chain, errors) =\u003e\n{\n    // Only if client.IsEncrypted is enabled\n    printf(\"validate ssl/tls certificate\");\n    // return true if certificate is valid\n    return true;\n});\n```\n\n```csharp\n// open connection if closed\nclient.To.Open(new Host(\"127.0.0.1\", 8080));\n\n// close connection if opened\nclient.To.Close();\n\n// send raw data if connected\nclient.To.Data(new byte[2] { 128, 255 });\nclient.To.Data(\"hello world\", NE.Encoding.UTF8);\n\n// send event if connected\nclient.To.Event(\"name\", new byte[2] { 128, 255 });\nclient.To.Event(\"name\", \"hello world\", NE.Encoding.UTF8);\n\n// enable encryption (must call before client.To.Open)\nclient.To.Encryption(true);\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eServer\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nTCP.Server server = new TCP.Server(framing: true);\n```\n\n```csharp\nserver.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nserver.On.Close(() =\u003e\n{\n    printf(\"connection closed\");\n});\n\nserver.On.Error((exception) =\u003e\n{\n    printf(\"connection error on open\");\n});\n\nserver.On.Accept((client) =\u003e\n{\n    client.On.Modify((socket) =\u003e\n    {\n        printf(\"modify client socket e.g Enable NoDelay\");\n    });\n\n    client.On.Open(() =\u003e\n    {\n        printf(\"client connected\");\n    });\n\n    client.On.Data((bytes) =\u003e\n    {\n        printf(\"client receive a raw data\");\n    });\n\n    client.On.Event((name, bytes) =\u003e\n    {\n        printf(\"client receive a event\");\n    });\n\n    client.On.Close(() =\u003e\n    {\n        printf(\"client disconnected\");\n    });\n});\n\nserver.On.Modify((socket) =\u003e\n{\n    printf(\"called before try open connection.\");\n});\n```\n\n```csharp\n// open connection\nserver.To.Open(new Host(\"1.1.1.1\", 1111));\n\n// close connection\nserver.To.Close();\n\n// enable encryption support (must called before server.To.Open)\nserver.To.Encryption(enable: true, @mypfx, @mypfxpassword, SslProtocols.Tls12);\n\n// broadcast raw data for all connected client\nserver.To.DataBroadcast(\"text buffer\");\nserver.To.DataBroadcast(new byte[] { 1, 2, 3 });\n\n// broadcast event (netly event) for all connected client\nserver.To.EventBroadcast(\"event name\", \"text buffer\");\nserver.To.EventBroadcast(\"event name\", new byte[] { 1, 2, 3 });\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003eUDP\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eClient\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nUDP.Client client = new UDP.Client();\n```\n\n```csharp\nclient.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nclient.On.Close(() =\u003e\n{\n    printf(\"connection closed\");\n});\n\nclient.On.Error((exception) =\u003e\n{\n    printf(\"connection error on open\");\n});\n\nclient.On.Data((bytes) =\u003e\n{\n    printf(\"connection received a raw data\");\n});\n\nclient.On.Event((name, eventBytes) =\u003e\n{\n    printf(\"connection received a event\");\n});\n\nclient.On.Modify((socket) =\u003e\n{\n   printf(\"called before try open connection.\");\n});\n```\n\n```csharp\n// open connection if closed\nclient.To.Open(new Host(\"127.0.0.1\", 8080));\n\n// close connection if opened\nclient.To.Close();\n\n// send raw data if connected\nclient.To.Data(new byte[2] { 128, 255 });\nclient.To.Data(\"hello world\", NE.Encoding.UTF8);\n\n// send event if connected\nclient.To.Event(\"name\", new byte[2] { 128, 255 });\nclient.To.Event(\"name\", \"hello world\", NE.Encoding.UTF8);\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eServer\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nUDP.Server server = new UDP.Server();\n```\n\n```csharp\nserver.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nserver.On.Close(() =\u003e\n{\n    printf(\"connection closed\");\n});\n\nserver.On.Error((exception) =\u003e\n{\n    printf(\"connection error on open\");\n});\n\nserver.On.Accept((client) =\u003e\n{\n    client.On.Open(() =\u003e\n    {\n        printf(\"client connected\");\n    });\n\n    client.On.Close(() =\u003e\n    {\n        // Only if use connection is enabled.\n        printf(\"client disconnected\");\n    });\n\n    client.On.Data((bytes) =\u003e\n    {\n        printf(\"client received a raw data\");\n    });\n\n    client.On.Event((name, bytes) =\u003e\n    {\n        printf(\"client received a event\");\n    });\n});\n```\n\n```csharp\n// open connection\nserver.To.Open(new Host(\"127.0.0.1\", 8080));\n\n// close connection\nserver.To.Close();\n\n// broadcast raw data for all connected client\nserver.To.DataBroadcast(\"text buffer\");\nserver.To.DataBroadcast(new byte[] { 1, 2, 3 });\n\n// broadcast event (netly event) for all connected client\nserver.To.EventBroadcast(\"event name\", \"text buffer\");\nserver.To.EventBroadcast(\"event name\", new byte[] { 1, 2, 3 });\n\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003eHTTP\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eClient\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nHTTP.Client client = new HTTP.Client();\n\n// add http header for request\nclient.Headers.Add(\"Content-Type\", \"json\");\nclient.Headers.Add(\"Token\", \"ImGui.h\");\n\n// add http url queries e.g: https://www.alec1o.com/?page=about\u0026version=4\nclient.Queries.Add(\"page\", \"about\");\nclient.Queries.Add(\"version\", \"4\");\n\n// set request timeout (ms) default 15s (15000ms), 0 or negative value means infinite timeout.\nclient.Timeout = 6000; // 6s\n\n// is opened: while is requesting\nbool isFetching = client.IsOpened;\n```\n\n```csharp\nHttpClient http = null;\n\n// called before try connect to server\n// modify the HttpClient object\nclient.On.Modify((HttpClient instance) =\u003e\n{\n    http = instance;\n});\n\n// connection is opened and fetch server.\nclient.On.Open((response) =\u003e\n{\n    // you can use \"http\" instance on this scope (isn't null)\n    if (http.\u003cfoo\u003e == \u003cbar\u003e) { ... }\n});\n\n// erro on fetch, it can be timeout or whatever error\n// but if you receives error it mean the operation is called or done\nclient.On.Error((Exception exception) =\u003e\n{\n    Ny.Logger.PushError(exception);\n});\n\n// connection is closed with fetch server.\nclient.On.Close(() =\u003e\n{\n     if (http.\u003cbar\u003e == \u003cfoo\u003e) { ... }\n});\n```\n\n```csharp\n\n// used to fetch a server\nclient.To.Open(\"method e.g GET\", \"url\", \"body, allow null\");\n\n// used for cancel opened request\nclient.To.Close();\n\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eServer\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nHTTP.Server server = new HTTP.Server();\n\n// return true if server is serve http context\nbool isServe = server.IsOpened;\n\n```\n\n```csharp\n\nserver.On.Open(() =\u003e\n{\n    // http server opened\n});\nserver.On.Close(() =\u003e\n{\n    // http server closed\n});\n\nserver.On.Error((exception) =\u003e\n{\n    // http server open error\n});\n\nserver.On.Modify((httpListener) =\u003e\n{\n    // HttpListener instance, called before try open connection.\n});\n\n// Open http server connection\nserver.To.Open(new Uri(\"http://127.0.0.1:8080/\"));\n\n// Close http server connection\nserver.To.Close();\n```\n\n##### Map\n\n```csharp\n// Map path\nserver.Map.Get(\"/\", async (req, res) =\u003e {\n    // Handle async: GET\n})\n\nserver.Map.Post(\"/user\", (req, res) =\u003e {\n    // Handle sync: POST\n});\n\n// map using dynamic URL\nserver.Map.Delete(\"/post/{userId}/group/{groupId}\", async (req, res)) =\u003e\n{\n    string userId = req.Param[\"userId\"];\n    string groupId = req.Param[\"groupId\"];\n\n    // Handle async: Delete from dynamic URL path\n});\n\nserver.Map.WebSocket(\"/echo\", (req, ws) =\u003e\n{\n    // Handle websocket connection from path\n});\n\n/*\nYou can map:\n * Get     # get request\n * Post    # post request\n * Delete  # delete request\n * Put     # put request\n * Patch   # patch request\n * Trace   # trace request\n * Options # options request\n * Head    # head request, (only head)\n * All     # all http nethod request\n * WebSocket   # websocket request\n*/\n\n```\n\n##### Middleware\n\n```csharp\n/*\n    Note: Middlewares is executed in added order.\n    BUT, LOCAL MIDDLEWARE HAVE PRIORITY THAN GLOBAL MIDDLEWARE\n*/\n\n// Global Middleware (*don't have workflow path)\nserver.Middleware.Add(async (req, res, next) =\u003e {\n    // verify request timer\n    Stopwatch watch = new Stopwatch(); // init timer\n\n    next(); // call another middleware.\n\n    watch.Stop(); // stop timer\n\n    res.Header.Add(\"Request-Timer\", watch.ElapsedMilliseconds.ToString());\n});\n\n\n// Local middleware (have workflow path)\nserver.Middleware.Add(\"/admin\", async (req, res, next) =\u003e {\n\n    if (MyApp.CheckAdminByHeader(req.Header))\n    {\n        res.Header.Add(\"Admin-Token\", MyApp.RefreshAdminHeaderToken(req));\n        // call next middleware\n        next();\n        // now. all middleware is executed. (because this is two way middleware)\n        res.Header.Add(\"Request-Delay\", (DateTime.UtcNow - timer)());\n    }\n    else\n    {\n        res.Header.Add(\"Content-Type\", \"application/json;charset=UTF-8\");\n        await res.Send(404, \"{ 'error': 'invalid request.' }\");\n        // skip other middlewares:\n        // next();\n    }\n});\n```\n\n##### Body Parser\n\n```cs\n// Register parse middleware\nserver.Middleware.Add((request, response, next) =\u003e\n{\n    if (request.Enctype == HTTP.Enctype.Json)\n    {\n        request.Body.RegisterParse(true, (Type type) =\u003e\n        {\n            // e.g. using dotnet \u003e= 6 @System.Text.Json\n            return JsonSerializer.Deserialize(request.Body.Text, type);\n        });\n    }\n\n    ...\n\n    next();\n});\n\n// Usage of body parser.\nserver.Map.Post(\"/register\", (request, response) =\u003e\n{\n    var data = request.Body.Parse\u003cMyLoginInput\u003e();\n    ...\n});\n\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003eRUDP\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eClient\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nRUDP.Client client = new RUDP.Client();\n```\n\n```csharp\nclient.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nclient.On.Close(() =\u003e\n{\n    printf(\"connection closed\");\n});\n\nclient.On.Error((exception) =\u003e\n{\n    printf(\"connection error on open\");\n});\n\nclient.On.Data((bytes, type) =\u003e\n{\n    printf(\"connection received a raw data\");\n});\n\nclient.On.Event((name, bytes, type) =\u003e\n{\n    printf(\"connection received a event\");\n});\n\nclient.On.Modify((socket) =\u003e\n{\n    printf(\"called before try open connection.\");\n});\n```\n\n```csharp\n// open connection if closed\nclient.To.Open(new Host(\"127.0.0.1\", 8080));\n\n// close connection if opened\nclient.To.Close();\n\n// send raw data if connected\nclient.To.Data(new byte[2] { 128, 255 }, RUDP.Unreliable);\nclient.To.Data(\"hello world\", NE.Encoding.UTF8, RUDP.Reliable);\n\n// send event if connected\nclient.To.Event(\"name\", new byte[2] { 128, 255 }, RUDP.Unreliable);\nclient.To.Event(\"name\", \"hello world\", NE.Encoding.UTF8, RUDP.Reliable);\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eServer\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nRUDP.Server server = new RUDP.Server();\n```\n\n```csharp\nserver.On.Open(() =\u003e\n{\n    printf(\"connection opened\");\n});\n\nserver.On.Close(() =\u003e\n{\n    printf(\"connection closed\");\n});\n\nserver.On.Error((exception) =\u003e\n{\n    printf(\"connection error on open\");\n});\n\nserver.On.Accept((client) =\u003e\n{\n    client.On.Open(() =\u003e\n    {\n        printf(\"client connected\");\n    });\n\n    client.On.Close(() =\u003e\n    {\n        // Only if use connection is enabled.\n        printf(\"client disconnected\");\n    });\n\n    client.On.Data((bytes, type) =\u003e\n    {\n        if (type == RUDP.Reliable) { ... }\n        else if (type == RUDP.Unreliable) { ... }\n        else {  ... } /* type == RUDP.Sequenced */\n\n\n        printf(\"client received a raw data\");\n    });\n\n    client.On.Event((name, type) =\u003e\n\n        if (type == RUDP.Reliable) { ... }\n        else if (type == RUDP.Unreliable) { ... }\n        else {  ... } /* type == RUDP.Sequenced */\n\n        printf(\"client received a event\");\n    });\n});\n```\n\n```csharp\n// open connection\nserver.To.Open(new Host(\"127.0.0.1\", 8080));\n\n// close connection\nserver.To.Close();\n\n// broadcast raw data for all connected client\nserver.To.DataBroadcast(\"text buffer\", RUDP.Unreliable);\nserver.To.DataBroadcast(new byte[] { 1, 2, 3 }, RUDP.Reliable);\nserver.To.DataBroadcast(new byte[] { 3, 2, 1 }, RUDP.Sequenced);\n\n// broadcast event (netly event) for all connected client\nserver.To.EventBroadcast(\"event name\", \"text buffer\", RUDP.Unreliable);\nserver.To.EventBroadcast(\"event name\", new byte[] { 1, 2, 3 }, RUDP.Reliable);\nserver.To.EventBroadcast(\"event name\", new byte[] { 3, 2, 1 }, RUDP.Sequenced);\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003eWebSocket\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eClient\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\n\nHTTP.WebSocket client = new HTTP.WebSocket();\n```\n\n```csharp\nclient.On.Open(() =\u003e\n{\n    // websocket connection opened\n});\n\nclient.On.Close(() =\u003e\n{\n    // websocket connection closed\n});\n\nclient.On.Error((exception) =\u003e\n{\n    // error on open websocket connectin\n});\n\nclient.On.Data((bytes, type) =\u003e\n{\n    if (type == HTTP.Binary) { ... }\n    else if (type == HTTP.Text) { ... }\n    else { /* NOTE: it's imposible */ }\n\n    // raw data received from server\n});\n\nclient.On.Event((name, bytes, type) =\u003e\n{\n    if (type == HTTP.Binary) { ... }\n    else if (type == HTTP.Text) { ... }\n    else { /* NOTE: it's imposible */ }\n\n    // event received from server\n});\n\nclient.On.Modify((wsSocket) =\u003e\n{\n    // modify websocket socket\n});\n```\n\n```csharp\n// open websocket client connection\nclient.To.Open(new Uri(\"ws://127.0.0.1:8080/echo\"));\n\n// close websocket client connection\nclient.To.Close();\n\n// send raw data for server\n//      text message\nclient.To.Data(\"my message\", HTTP.Text);\n//      binnary message\nclient.To.Data(NE.GetBytes(\"my buffer\"), HTTP.Binary);\n\n// send event (netly event) for server\n//      text message\nclient.To.Event(\"event name\", \"my message\", HTTP.Text);\n//      binnary message\nclient.To.Data(\"event name\", NE.GetBytes(\"my buffer\"), HTTP.Binary);\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eServer\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Netly;\nusing Netly.Interfaces;\n\nHTTP.Server server = new HTTP.Server();\n\nIHTTP.WebSocket[] Clients = server.WebSocketClients;\n```\n\n```csharp\nserver.Map.WebSocket(\"/chat/{token}\", async (req, ws) =\u003e\n{\n    // Accept websocket from dynamic path\n    string token = req.Params[\"token\"];\n\n    // validate websocket connection from params\n    if (Foo.Bar(token) == false)\n    {\n        ws.To.Close();\n    }\n\n    ws.On.Modify(...);\n    ws.On.Open(...);\n    ws.On.Close(...);\n    ws.On.Data(...);\n    ws.On.Event(...);\n});\n\n\nserver.Map.Websocket(\"/echo\", (req, ws) =\u003e\n{\n    // Handle websocket on /echo path\n\n    ws.On.Modify((wsSocket) =\u003e\n    {\n        // modify server-side websocket ocket\n    });\n\n    ws.On.Open(() =\u003e\n    {\n        // server-side websocket connection opened\n    });\n\n    ws.On.Close(() =\u003e\n    {\n        // server-side websocket connection closed\n    });\n\n    ws.On.Data((bytes, type) =\u003e\n    {\n        if (type == HTTP.Binary) { ... }\n        else if (type == HTTP.Text) { ... }\n        else { /* NOTE: it's imposible */ }\n\n        // server-side websocket received raw data\n    });\n\n    ws.On.Event((name, bytes, type) =\u003e\n    {\n        if (type == HTTP.Binary) { ... }\n        else if (type == HTTP.Text) { ... }\n        else { /* NOTE: it's imposible */ }\n\n        // server-side websocket received event\n    });\n});\n```\n\n```csharp\nserver.On.Open(() =\u003e\n{\n    // http server opened\n});\nserver.On.Close(() =\u003e\n{\n    // http server closed\n});\n\nserver.On.Error((exception) =\u003e\n{\n    // http server open error\n});\n\nserver.On.Modify((httpListener) =\u003e\n{\n    // HttpListener instance, called before try open connection.\n});\n\n// Open http server connection\nserver.To.Open(new Uri(\"http://127.0.0.1:8080/\"));\n\n// Close http server connection\nserver.To.Close();\n```\n\n```csharp\n// open websocket client connection\nserver.To.Open(new Uri(\"ws://127.0.0.1:8080/echo\"));\n\n// close websocket client connection\nserver.To.Close();\n\n// broadcast raw data for all connected websocket socket\n//      text message\nserver.To.WebsocketDataBroadcast(\"my message\", HTTP.Text);\n//      binnary message\nserver.To.WebsocketDataBroadcast(NE.GetBytes(\"my buffer\"), HTTP.Binary);\n\n// broadcast event (netly event) for all connected websocket socket\n//      text message\nserver.To.WebsocketEventBroadcast(\"event name\", \"my message\", HTTP.Text);\n//      binnary message\nserver.To.WebsocketEventBroadcast(\"event name\", NE.GetBytes(\"my buffer\"), HTTP.Binary);\n```\n\n\u003c/details\u003e\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003ca href=\"https://github.com/alec1o/Byter\"\u003e\u003csub\u003eByter\u003cstrong\u003e\u003c/strong\u003e\u003c/sub\u003e\u003c/a\u003e\u003c/th\u003e\n\u003ctd\u003e\n\n###### For more information and details see [Byter's](https://github.com/alec1o/Byter) official information\n\n\u003e \u003csub\u003eByter documentation: [alec1o/Byter](https://github.com/alec1o/Byter)\u003c/sub\u003e\n\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003ePrimitive\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Byter;\n```\n\n-   \u003cstrong\u003e\u003csub\u003eSerialize\u003c/sub\u003e\u003c/strong\u003e \u003csub\u003e_(have +20 types of data supported, e.g. enum, bool, array, list, class,\n    struct,... [see official docs](https://github.com/alec1o/Byter)_\u003c/sub\u003e\n\n    ```csharp\n    Primitive primitive = new();\n\n    // add element\n\n    primitive.Add.ULong(1024);                 // e.g. Id\n    primitive.Add.DateTime(DateTime.UtcNow);   // e.g. Sent Time\n    primitive.Add.Struct(new Student() {...}); // e.g Student\n    primitive.Add.Class(new Employee() {...}); // e.g Employee\n    ...\n\n    // get buffer\n    byte[] buffer = primitive.GetBytes();\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eDeserialize\u003c/sub\u003e\u003c/strong\u003e\n\n    ```csharp\n    // WARNING: Need primitive buffer to deserialize\n    Primitive primitive = new(...buffer);\n\n    ulong id = primitive.Get.ULong();\n    DateTime sentTime = primitive.Get.DateTime();\n    Student student = primitive.Get.Struct\u003cStudent\u003e();\n    Employee employee = primitive.Get.Class\u003cEmployee\u003e();\n\n    /*\n        * NOTE: Primitive don't make exception when diserialize error,\n        * don't need try/catch block\n    */\n    if (primitive.IsValid is false)\n    {\n        // discart this. +1/all failed on deserialize\n        return;\n    }\n\n    // deserialized sucessful\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003e\\*Dynamic Read Technical\u003c/sub\u003e\u003c/strong\u003e\n\n    ```csharp\n    Primitive primitive = new(...buffer);\n\n    var topic = primitive.Get.Enum\u003cTopic\u003e();\n\n    if(!primitive.IsValid) return; // discart this, topic not found.\n\n    switch(topic)\n    {\n        case Topic.Student:\n        {\n            // read student info e.g.\n            var student = primitive.Get.Struct\u003cStudent\u003e();\n            ...\n            return;\n        }\n\n        case Topic.Employee:\n        {\n            // read employee info e.g.\n            var employee = primitive.Get.Class\u003cEmployee\u003e();\n            ...\n            return;\n        }\n\n        default:\n        {\n            // discart this, topic not found.\n            ...\n            return;\n        }\n    }\n    ```\n\n---\n\n###### Warning\n\nPrimitive can serialize/deserialize complex data, e.g. (T[], List\u003cT\u003e, Class, Struct, Enum).\u003cbr\u003e\nBut when you want to deserialize your (Class, Structure, List\u003cClass/Struct\u003e, Class/Struct[]), It must have:\n\n-   (generic and public constructor: is a public constructor with no arguments, e.g. which allows:\n    ```csharp\n    Human human = new Human();\n    ```\n-   And the class/struct property must have public access and { get; set; } or not private\n    for example. (In byter programming, _ONLY PROPERTIES THAT CAN BE READ AND WRITTEN WILL BE SERIALIZED AND DESERIALIZED)_\n\n    ```csharp\n    // valid\n    public string Name;\n    public string Name { get; set; }\n    internal string Name; // !!! if visible from Byter\n    internal string Name { get; set; }; // !!! if visible from Byter\n\n    // invalid\n    private string Name;\n    private string Name { get; set; }\n    internal string Name; // !!! if unvisible from Byter\n    internal string Name { get; set; }; // !!! if unvisible from Byter\n    ```\n\n---\n\n###### Example\n\n-   \u003cstrong\u003e\u003csub\u003eSample of complex data\u003c/sub\u003e\u003c/strong\u003e\n\n    ```cs\n    public class Human\n    {\n        public BigInteger IdNumber { get; set; }\n        public string FirstName { get; set; }\n        public string LastName { get; set; }\n        public DateTime DateOfBirth { get; set; }\n        public GenderType Gender { get; set; } // enum\n        public byte[] Picture { get; set; }\n\n    }\n\n    public class Employee\n    {\n        public Human Human { get; set; }\n        public string Position { get; set; }\n        public DateTime HireDate { get; set; }\n        public int YearsOfService { get; set; }\n    }\n\n    public struct Student\n    {\n        public string Major { get; set; }\n        public DateTime EnrollmentDate { get; set; }\n        public List\u003cBook\u003e Books { get; set; }\n\n    }\n\n    public class Book\n    {\n        public string Title { get; set; }\n        public string Author { get; set; }\n        public string ISBN { get; set; }\n        public int PublicationYear { get; set; }\n        public string Publisher { get; set; }\n        public decimal Price { get; set; }\n    }\n    ```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eExtension\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing Byter;\n```\n\n-   \u003cstrong\u003e\u003csub\u003eGlobal Default\n    Encoding\u003c/sub\u003e\u003c/strong\u003e [\u003ci\u003e\u003csub\u003e(source code spec)\u003c/sub\u003e\u003c/i\u003e](https://github.com/alec1o/Byter/blob/main/src/src/extension/StringExtension.cs#L8)\n\n    ```csharp\n    // update global defaut encoding. Default is UTF8\n    StringExtension.Default = Encoding.Unicode; // Unicode is UTF16\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eConvert string to byte[]\u003c/sub\u003e\u003c/strong\u003e\n\n    ```csharp\n    // using global encoding (*UTF8)\n    byte[] username  = \"@alec1o\".GetBytes();\n\n    // using UNICODE (*UTF16) encoding\n    byte[] message = \"Hello 👋 World 🌎\".GetBytes(Encoding.Unicode);\n\n    // using UTF32 encoding\n    string secreatWord = \"I'm not human, I'm  a concept.\";\n    byte[] secreat = secreatWord.GetBytes(Encoding.UTF32);\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eConvert byte[] to string\u003c/sub\u003e\u003c/strong\u003e\n\n    ```csharp\n    // using global encoding (*UTF8)\n    string username  = new byte[] { ... }.GetString();\n\n    // using UNICODE (*UTF16) encoding\n    string message = new byte[] { ... }.GetString(Encoding.Unicode);\n\n    // using UTF32 encoding\n    byte[] secreat = new byte[] { ... };\n    string secreatWord = secreat.GetString(Encoding.UTF32);\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eCapitalize string\u003c/sub\u003e\u003c/strong\u003e\n\n    ```rb\n    string name = \"alECio furanZE\".ToCapitalize();\n    # Alecio Furanze\n\n    string title = \"i'M noT humAn\";\n    title = title.ToCapitalize();\n    # I'm Not Human\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eUpperCase string\u003c/sub\u003e\u003c/strong\u003e\n\n    ```rb\n    string name = \"alECio furanZE\".ToUpperCase();\n    # ALECIO FURANZE\n\n    string title = \"i'M noT humAn\";\n    title = title.ToUpperCase();\n    # I'M NOT HUMAN\n    ```\n\n-   \u003cstrong\u003e\u003csub\u003eLowerCase string\u003c/sub\u003e\u003c/strong\u003e\n\n    ```rb\n    string name = \"ALEciO FUraNZE\".ToLowerCase();\n    # alecio furanze\n\n    string title = \"i'M Not huMAN\";\n    title = title.ToLowerCase();\n    # i'm not human\n    ```\n\n\u003c/details\u003e\n\n\u003ca href=\"###\"\u003e\u003cimg src=\"/static/transparent-horizontal-1px-2048px.png\" width=\"100%\"\u003e\u003ca/\u003e\n\n\u003c/td\u003e\n\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cbr\u003e\n\n##### Usage\n\n\u003e \u003csub\u003eIntegration and interaction example codes\u003c/sub\u003e\n\n\u003ctable\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003e\u003cstrong\u003eStandard\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eConsole\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing System;\nusing Netly;\n\npublic class Program\n{\n    private static void Main(string[] args)\n    {\n        UDP.Client client = new UDP.Client();\n\n        client.On.Open(() =\u003e\n        {\n            Console.WriteLine(\u003csome-text-here\u003e);\n        };\n\n        client.On.Close(() =\u003e\n        {\n            Console.WriteLine(\u003csome-text-here\u003e);\n        };\n\n        client.On.Error((exception) =\u003e\n        {\n            Console.WriteLine(\u003csome-text-here\u003e);\n        };\n\n        while(true)\n        {\n            if(!client.IsOpened)\n            {\n                client.To.Open(new Host(\"1.1.1.1\", 1111));\n            }\n            else\n            {\n                Console.WriteLine(\"Message: \");\n                string message = Console.ReadLine();\n                client.To.Data(message ?? \"No message.\", NE.Encoding.UTF8);\n            }\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003e\u003cstrong\u003eFlax Engine\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eScript\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing System;\nusing FlaxEngine;\nusing Netly;\n\npublic class Example : Script\n{\n    public string message;\n\n    internal UDP.Client client;\n\n    public override void Awake()\n    {\n        client = new UDP.Client();\n\n        client.On.Open(() =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n\n        client.On.Close(() =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n\n        client.On.Error((exception) =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n    }\n\n    public override void Start()\n    {\n        client.To.Open(new Host(\"1.1.1.1\", 1111));\n    }\n\n    public override void Update()\n    {\n        if(!client.IsOpened)\n        {\n             client.To.Open(new Host(\"1.1.1.1\", 1111));\n        }\n        else\n        {\n            if (Input.GetKeyDown(KeyCode.Space))\n            {\n                client.To.Data(message ?? \"No message.\", NE.Encoding.UTF8);\n            }\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003e\u003cstrong\u003eUnity Engine\u003c/strong\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\n\u003cdetails\u003e\u003csummary\u003e📄 \u003cstrong\u003e\u003csup\u003e\u003csub\u003eMonoBehaviour\u003c/sub\u003e\u003c/sup\u003e\u003c/strong\u003e\u003c/summary\u003e\n\n```csharp\nusing System;\nusing FlaxEngine;\nusing Netly;\n\npublic class Example : MonoBehaviour\n{\n    public string message;\n\n    internal UDP.Client client;\n\n    private void Awake()\n    {\n        client = new UDP.Client();\n\n        client.On.Open(() =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n\n        client.On.Close(() =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n\n        client.On.Error((exception) =\u003e\n        {\n            Debug.Log(\u003csome-text-here\u003e);\n        };\n    }\n\n    private void Start()\n    {\n        client.To.Open(new Host(\"1.1.1.1\", 1111));\n    }\n\n    private void Update()\n    {\n        if(!client.IsOpened)\n        {\n             client.To.Open(new Host(\"1.1.1.1\", 1111));\n        }\n        else\n        {\n            if (Input.GetKeyDown(KeyCode.Space))\n            {\n                client.To.Data(message ?? \"No message.\", NE.Encoding.UTF8);\n            }\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\n\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctr\u003e\n\u003cth align=\"center\" valign=\"top\"\u003e\u003csub\u003e\u003ci\u003eWARNING:\u003c/i\u003e\u003c/sub\u003e\u003c/th\u003e\n\u003ctd\u003e\n\n\u003csub\u003e\n\u003cstrong\u003eInitialize event handlers once, not in loops\u003c/strong\u003e. Set up handlers with `\u003cprotocol\u003e.\u003cclient|server\u003e.On.\u003cevent\u003e` methods in initialization methods like `Awake()` or `Start()`. Avoid repeatedly setting these up in update loops to maintain performance.\n\u003c/sub\u003e\n\u003cbr\u003e\n\u003cbr\u003e\n\u003csub\u003e\n\u003cstrong\u003eHandle protocol actions wisely\u003c/strong\u003e. Use `\u003cprotocol\u003e.\u003cclient|server\u003e.To.\u003caction\u003e` methods, such as `\u003cprotocol\u003e.\u003cclient|server\u003e.To.Open()`, `\u003cprotocol\u003e.\u003cclient|server\u003e.To.Data()`, and `\u003cprotocol\u003e.\u003cclient|server\u003e.To.Close()`, with careful management. Ensure you only open a connection when it's not already open and send data only when the connection is confirmed as active. Avoid calling these methods in tight loops.\n\u003c/sub\u003e\n\n\u003cbr\u003e\u003cbr\u003e\n\n```csharp\n// OK 100% Recommended\nprivate void Start()\n{\n    var client = ...;\n\n    client.On.Open(() =\u003e ...); // e.g generic handler\n    client.On.Open(() =\u003e ...); // e.g only to send \"Hi\"\n    client.On.Event((name, bytes, ?) =\u003e ...); // e.g generic event handler\n    client.On.Event((name, bytes, ?) =\u003e ...); // e.g only to handle A event\n    client.On.Event((name, bytes, ?) =\u003e ...); // e.g only to handle B event\n\n    client.To.Open(...);\n}\n```\n\n```csharp\npublic void Update()\n{\n    client.To.Open(...);                 // [OK? - May Not In Loop?]\n    client.To.Data(...);                 // [OK? - May Not In Loop?]\n    client.To.Event(...);                // [OK? - May Not In Loop?]\n    client.To.Close(...);                // [OK? - May Not In Loop?]\n\n    ws.On.Open(() =\u003e ...);               // [BAD - Never In Loop]\n    ws.On.Close(() =\u003e ... );             // [BAD - Never In Loop]\n    ws.On.Data((bytes) =\u003e ... );         // [BAD - Never In Loop]\n    ws.On.Error((exception) =\u003e ... );    // [BAD - Never In Loop]\n    ws.On.Event((name, bytes) =\u003e  ... ); // [BAD - Never In Loop]\n}\n```\n\n\u003cbr\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n","funding_links":["https://www.buymeacoffee.com/alec1o","https://img.buymeacoffee.com/button-api/?text=Buy"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falec1o%2Fnetly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falec1o%2Fnetly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falec1o%2Fnetly/lists"}