{"id":13413623,"url":"https://github.com/lesismal/nbio","last_synced_at":"2025-05-13T19:12:23.830Z","repository":{"id":38325805,"uuid":"236162999","full_name":"lesismal/nbio","owner":"lesismal","description":"Pure Go 1000k+ connections solution, support tls/http1.x/websocket and basically compatible with net/http, with high-performance and low memory cost, non-blocking, event-driven, easy-to-use.","archived":false,"fork":false,"pushed_at":"2025-04-26T18:03:49.000Z","size":3296,"stargazers_count":2448,"open_issues_count":0,"forks_count":162,"subscribers_count":34,"default_branch":"master","last_synced_at":"2025-04-27T05:48:44.996Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","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/lesismal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-01-25T11:46:54.000Z","updated_at":"2025-04-26T05:03:47.000Z","dependencies_parsed_at":"2024-01-18T09:52:15.110Z","dependency_job_id":"88cb8c6a-d006-4393-856e-266a2eb8f99c","html_url":"https://github.com/lesismal/nbio","commit_stats":{"total_commits":1043,"total_committers":24,"mean_commits":"43.458333333333336","dds":0.6251198465963567,"last_synced_commit":"a3458ca643bae26bdc2eb236dd26574cf087f24f"},"previous_names":[],"tags_count":91,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lesismal%2Fnbio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lesismal%2Fnbio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lesismal%2Fnbio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lesismal%2Fnbio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lesismal","download_url":"https://codeload.github.com/lesismal/nbio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251094603,"owners_count":21535325,"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":[],"created_at":"2024-07-30T20:01:44.774Z","updated_at":"2025-04-27T05:48:49.797Z","avatar_url":"https://github.com/lesismal.png","language":"Go","funding_links":[],"categories":["Networking","Go","网络","Relational Databases"],"sub_categories":["Transliteration","音译","Uncategorized"],"readme":"# NBIO - NON-BLOCKING IO\r\n\r\n\r\n\u003c!-- [![Slack][1]][2] --\u003e\r\n\r\n[![Mentioned in Awesome Go][3]][4] [![MIT licensed][5]][6] [![Go Version][7]][8] [![Build Status][9]][10] [![Go Report Card][11]][12]\r\n\r\n[1]: https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true\u0026logo=slack\u0026colorB=green\r\n[2]: https://join.slack.com/t/arpcnbio/shared_invite/zt-vh3g1z2v-qqoDp1hQ45fJZqwPrSz4~Q\r\n[3]: https://awesome.re/mentioned-badge-flat.svg\r\n[4]: https://github.com/avelino/awesome-go#networking\r\n[5]: https://img.shields.io/badge/license-MIT-blue.svg\r\n[6]: LICENSE\r\n[7]: https://img.shields.io/badge/go-%3E%3D1.16-30dff3?style=flat-square\u0026logo=go\r\n[8]: https://github.com/lesismal/nbio\r\n[9]: https://img.shields.io/github/actions/workflow/status/lesismal/nbio/autobahn.yml?branch=master\u0026style=flat-square\u0026logo=github-actions\r\n[10]: https://github.com/lesismal/nbio/actions?query=workflow%3autobahn\r\n[11]: https://goreportcard.com/badge/github.com/lesismal/nbio\r\n[12]: https://goreportcard.com/report/github.com/lesismal/nbio\r\n[13]: https://codecov.io/gh/lesismal/nbio/branch/master/graph/badge.svg\r\n[14]: https://codecov.io/gh/lesismal/nbio\r\n[15]: https://godoc.org/github.com/lesismal/nbio?status.svg\r\n[16]: https://godoc.org/github.com/lesismal/nbio\r\n\r\n\r\n## Contents\r\n\r\n- [NBIO - NON-BLOCKING IO](#nbio---non-blocking-io)\r\n\t- [Contents](#contents)\r\n\t- [Features](#features)\r\n\t\t- [Cross Platform](#cross-platform)\r\n\t\t- [Protocols Supported](#protocols-supported)\r\n\t\t- [Interfaces](#interfaces)\r\n\t- [Quick Start](#quick-start)\r\n\t- [Examples](#examples)\r\n\t\t- [TCP Echo Examples](#tcp-echo-examples)\r\n\t\t- [UDP Echo Examples](#udp-echo-examples)\r\n\t\t- [TLS Examples](#tls-examples)\r\n\t\t- [HTTP Examples](#http-examples)\r\n\t\t- [HTTPS Examples](#https-examples)\r\n\t\t- [Websocket Examples](#websocket-examples)\r\n\t\t- [Websocket TLS Examples](#websocket-tls-examples)\r\n\t\t- [Use With Other STD Based Frameworkds](#use-with-other-std-based-frameworkds)\r\n\t\t- [More Examples](#more-examples)\r\n\t- [1M Websocket Connections Benchmark](#1m-websocket-connections-benchmark)\r\n\t- [Magics For HTTP and Websocket](#magics-for-http-and-websocket)\r\n\t\t- [Different IOMod](#different-iomod)\r\n\t\t- [Using Websocket With Std Server](#using-websocket-with-std-server)\r\n\t- [Credits](#credits)\r\n\t- [Contributors](#contributors)\r\n\t- [Star History](#star-history)\r\n\r\n## Features\r\n### Cross Platform\r\n- [x] Linux: Epoll with LT/ET/ET+ONESHOT supported, LT as default\r\n- [x] BSD(MacOS): Kqueue\r\n- [x] Windows: Based on std net, for debugging only\r\n\r\n### Protocols Supported\r\n- [x] TCP/UDP/Unix Socket supported\r\n- [x] TLS supported\r\n- [x] HTTP/HTTPS 1.x supported\r\n- [x] Websocket supported, [Passes the Autobahn Test Suite](https://lesismal.github.io/nbio/websocket/autobahn), `OnOpen/OnMessage/OnClose` order guaranteed\r\n\r\n### Interfaces\r\n- [x] Implements a non-blocking net.Conn(except windows)\r\n- [x] SetDeadline/SetReadDeadline/SetWriteDeadline supported\r\n- [x] Concurrent Write/Close supported(both nbio.Conn and nbio/nbhttp/websocket.Conn)\r\n\r\n\r\n## Quick Start\r\n\r\n```golang\r\npackage main\r\n\r\nimport (\r\n\t\"log\"\r\n\r\n\t\"github.com/lesismal/nbio\"\r\n)\r\n\r\nfunc main() {\r\n\tengine := nbio.NewEngine(nbio.Config{\r\n\t\tNetwork:            \"tcp\",//\"udp\", \"unix\"\r\n\t\tAddrs:              []string{\":8888\"},\r\n\t\tMaxWriteBufferSize: 6 * 1024 * 1024,\r\n\t})\r\n\r\n\t// hanlde new connection\r\n\tengine.OnOpen(func(c *nbio.Conn) {\r\n\t\tlog.Println(\"OnOpen:\", c.RemoteAddr().String())\r\n\t})\r\n\t// hanlde connection closed\r\n\tengine.OnClose(func(c *nbio.Conn, err error) {\r\n\t\tlog.Println(\"OnClose:\", c.RemoteAddr().String(), err)\r\n\t})\r\n\t// handle data\r\n\tengine.OnData(func(c *nbio.Conn, data []byte) {\r\n\t\tc.Write(append([]byte{}, data...))\r\n\t})\r\n\r\n\terr := engine.Start()\r\n\tif err != nil {\r\n\t\tlog.Fatalf(\"nbio.Start failed: %v\\n\", err)\r\n\t\treturn\r\n\t}\r\n\tdefer engine.Stop()\r\n\r\n\t\u003c-make(chan int)\r\n}\r\n```\r\n\r\n## Examples\r\n### TCP Echo Examples\r\n\r\n- [echo-server](https://github.com/lesismal/nbio_examples/blob/master/echo/server/server.go)\r\n- [echo-client](https://github.com/lesismal/nbio_examples/blob/master/echo/client/client.go)\r\n\r\n### UDP Echo Examples\r\n\r\n- [udp-server](https://github.com/lesismal/nbio-examples/blob/master/udp/server/server.go)\r\n- [udp-client](https://github.com/lesismal/nbio-examples/blob/master/udp/client/client.go)\r\n\r\n### TLS Examples\r\n\r\n- [tls-server](https://github.com/lesismal/nbio_examples/blob/master/tls/server/server.go)\r\n- [tls-client](https://github.com/lesismal/nbio_examples/blob/master/tls/client/client.go)\r\n\r\n### HTTP Examples\r\n\r\n- [http-server](https://github.com/lesismal/nbio_examples/blob/master/http/server/server.go)\r\n- [http-client](https://github.com/lesismal/nbio_examples/blob/master/http/client/client.go)\r\n\r\n### HTTPS Examples\r\n\r\n- [http-tls_server](https://github.com/lesismal/nbio_examples/blob/master/http/server_tls/server.go)\r\n- visit: https://localhost:8888/echo\r\n\r\n### Websocket Examples\r\n\r\n- [websocket-server](https://github.com/lesismal/nbio_examples/blob/master/websocket/server/server.go)\r\n- [websocket-client](https://github.com/lesismal/nbio_examples/blob/master/websocket/client/client.go)\r\n\r\n### Websocket TLS Examples\r\n\r\n- [websocket-tls-server](https://github.com/lesismal/nbio_examples/blob/master/websocket_tls/server/server.go)\r\n- [websocket-tls-client](https://github.com/lesismal/nbio_examples/blob/master/websocket_tls/client/client.go)\r\n\r\n### Use With Other STD Based Frameworkds\r\n\r\n- [echo-http-and-websocket-server](https://github.com/lesismal/nbio_examples/blob/master/http_with_other_frameworks/echo_server/echo_server.go)\r\n- [gin-http-and-websocket-server](https://github.com/lesismal/nbio_examples/blob/master/http_with_other_frameworks/gin_server/gin_server.go)\r\n- [go-chi-http-and-websocket-server](https://github.com/lesismal/nbio_examples/blob/master/http_with_other_frameworks/go-chi_server/go-chi_server.go)\r\n\r\n### More Examples\r\n\r\n- [nbio-examples](https://github.com/lesismal/nbio-examples)\r\n\r\n\r\n\r\n## 1M Websocket Connections Benchmark\r\n\r\nFor more details: [go-websocket-benchmark](https://github.com/lesismal/go-websocket-benchmark)\r\n\r\n```sh\r\n# lsb_release -a\r\nLSB Version:    core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch\r\nDistributor ID: Ubuntu\r\nDescription:    Ubuntu 20.04.6 LTS\r\nRelease:        20.04\r\nCodename:       focal\r\n\r\n# free\r\n              total        used        free      shared  buff/cache   available\r\nMem:       24969564    15656352     3422212        1880     5891000     8899604\r\nSwap:             0           0           0\r\n\r\n# cat /proc/cpuinfo | grep processor\r\nprocessor       : 0\r\nprocessor       : 1\r\nprocessor       : 2\r\nprocessor       : 3\r\nprocessor       : 4\r\nprocessor       : 5\r\nprocessor       : 6\r\nprocessor       : 7\r\nprocessor       : 8\r\nprocessor       : 9\r\nprocessor       : 10\r\nprocessor       : 11\r\nprocessor       : 12\r\nprocessor       : 13\r\nprocessor       : 14\r\nprocessor       : 15\r\n\r\n\r\n# taskset\r\nrun nbio_nonblocking server on cpu 0-7\r\n\r\n--------------------------------------------------------------\r\nBenchType  : BenchEcho\r\nFramework  : nbio_nonblocking\r\nTPS        : 104713\r\nEER        : 280.33\r\nMin        : 56.90us\r\nAvg        : 95.36ms\r\nMax        : 2.29s\r\nTP50       : 62.82ms\r\nTP75       : 65.38ms\r\nTP90       : 89.38ms\r\nTP95       : 409.55ms\r\nTP99       : 637.95ms\r\nUsed       : 47.75s\r\nTotal      : 5000000\r\nSuccess    : 5000000\r\nFailed     : 0\r\nConns      : 1000000\r\nConcurrency: 10000\r\nPayload    : 1024\r\nCPU Min    : 0.00%\r\nCPU Avg    : 373.53%\r\nCPU Max    : 602.33%\r\nMEM Min    : 978.70M\r\nMEM Avg    : 979.88M\r\nMEM Max    : 981.14M\r\n--------------------------------------------------------------\r\n```\r\n\r\n\r\n## Magics For HTTP and Websocket\r\n\r\n### Different IOMod\r\n\r\n| IOMod            |                                                                                                                  Remarks                                                                                                                  |\r\n| ---------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\r\n| IOModNonBlocking |                                                        There's no difference between this IOMod and the old version with no IOMod. All the connections will be handled by poller.                                                         |\r\n| IOModBlocking    | All the connections will be handled by at least one goroutine, for websocket, we can set Upgrader.BlockingModAsyncWrite=true to handle writing with a separated goroutine and then avoid Head-of-line blocking on broadcasting scenarios. |\r\n| IOModMixed       |                  We set the Engine.MaxBlockingOnline, if the online num is smaller than it, the new connection will be handled by single goroutine as IOModBlocking, else the new connection will be handled by poller.                   |\r\n\r\nThe `IOModBlocking` aims to improve the performance for low online service, it runs faster than std. \r\nThe `IOModMixed` aims to keep a balance between performance and cpu/mem cost in different scenarios: when there are not too many online connections, it performs better than std, or else it can serve lots of online connections and keep healthy.\r\n\r\n### Using Websocket With Std Server\r\n\r\n```golang\r\npackage main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"net/http\"\r\n\r\n\t\"github.com/lesismal/nbio/nbhttp/websocket\"\r\n)\r\n\r\nvar (\r\n\tupgrader = newUpgrader()\r\n)\r\n\r\nfunc newUpgrader() *websocket.Upgrader {\r\n\tu := websocket.NewUpgrader()\r\n\tu.OnOpen(func(c *websocket.Conn) {\r\n\t\t// echo\r\n\t\tfmt.Println(\"OnOpen:\", c.RemoteAddr().String())\r\n\t})\r\n\tu.OnMessage(func(c *websocket.Conn, messageType websocket.MessageType, data []byte) {\r\n\t\t// echo\r\n\t\tfmt.Println(\"OnMessage:\", messageType, string(data))\r\n\t\tc.WriteMessage(messageType, data)\r\n\t})\r\n\tu.OnClose(func(c *websocket.Conn, err error) {\r\n\t\tfmt.Println(\"OnClose:\", c.RemoteAddr().String(), err)\r\n\t})\r\n\treturn u\r\n}\r\n\r\nfunc onWebsocket(w http.ResponseWriter, r *http.Request) {\r\n\tconn, err := upgrader.Upgrade(w, r, nil)\r\n\tif err != nil {\r\n\t\tpanic(err)\r\n\t}\r\n\tfmt.Println(\"Upgraded:\", conn.RemoteAddr().String())\r\n}\r\n\r\nfunc main() {\r\n\tmux := \u0026http.ServeMux{}\r\n\tmux.HandleFunc(\"/ws\", onWebsocket)\r\n\tserver := http.Server{\r\n\t\tAddr:    \"localhost:8080\",\r\n\t\tHandler: mux,\r\n\t}\r\n\tfmt.Println(\"server exit:\", server.ListenAndServe())\r\n}\r\n```\r\n\r\n\r\n## Credits\r\n- [xtaci/gaio](https://github.com/xtaci/gaio)\r\n- [gorilla/websocket](https://github.com/gorilla/websocket)\r\n- [crossbario/autobahn](https://github.com/crossbario)\r\n\r\n\r\n## Contributors\r\nThanks Everyone:\r\n- [acgreek](https://github.com/acgreek)\r\n- [acsecureworks](https://github.com/acsecureworks)\r\n- [arunsathiya](https://github.com/arunsathiya)\r\n- [guonaihong](https://github.com/guonaihong)\r\n- [isletnet](https://github.com/isletnet)\r\n- [liwnn](https://github.com/liwnn)\r\n- [manjun21](https://github.com/manjun21)\r\n- [om26er](https://github.com/om26er)\r\n- [rfyiamcool](https://github.com/rfyiamcool)\r\n- [sunny352](https://github.com/sunny352)\r\n- [sunvim](https://github.com/sunvim)\r\n- [wuqinqiang](https://github.com/wuqinqiang)\r\n- [wziww](https://github.com/wziww)\r\n- [youzhixiaomutou](https://github.com/youzhixiaomutou)\r\n- [zbh255](https://github.com/zbh255)\r\n- [IceflowRE](https://github.com/IceflowRE)\r\n- [YanKawaYu](https://github.com/YanKawaYu)\r\n\r\n\r\n## Star History\r\n\r\n[![Star History Chart](https://api.star-history.com/svg?repos=lesismal/nbio\u0026type=Date)](https://star-history.com/#lesismal/nbio\u0026Date)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flesismal%2Fnbio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flesismal%2Fnbio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flesismal%2Fnbio/lists"}