{"id":13511632,"url":"https://github.com/tidwall/evio","last_synced_at":"2025-12-14T20:26:52.652Z","repository":{"id":40617786,"uuid":"96170782","full_name":"tidwall/evio","owner":"tidwall","description":"Fast event-loop networking for Go","archived":false,"fork":false,"pushed_at":"2023-10-22T11:35:20.000Z","size":443,"stargazers_count":5967,"open_issues_count":27,"forks_count":496,"subscribers_count":174,"default_branch":"master","last_synced_at":"2025-04-10T18:31:50.390Z","etag":null,"topics":["networking"],"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/tidwall.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}},"created_at":"2017-07-04T03:15:07.000Z","updated_at":"2025-04-09T10:38:09.000Z","dependencies_parsed_at":"2024-06-02T00:37:14.946Z","dependency_job_id":"c09033d4-798c-40a5-aaf6-cfcc39b759d9","html_url":"https://github.com/tidwall/evio","commit_stats":{"total_commits":135,"total_committers":4,"mean_commits":33.75,"dds":"0.022222222222222254","last_synced_commit":"fe6081760191618105c0671e6aa05f06e7c6e5a9"},"previous_names":["tidwall/shiny"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fevio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fevio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fevio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tidwall%2Fevio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tidwall","download_url":"https://codeload.github.com/tidwall/evio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052962,"owners_count":22006717,"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":["networking"],"created_at":"2024-08-01T03:01:02.090Z","updated_at":"2025-12-14T20:26:52.560Z","avatar_url":"https://github.com/tidwall.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n\u003cimg \n    src=\"logo.png\" \n    width=\"213\" height=\"75\" border=\"0\" alt=\"evio\"\u003e\n\u003cbr\u003e\n\u003ca href=\"https://godoc.org/github.com/tidwall/evio\"\u003e\u003cimg src=\"https://img.shields.io/badge/api-reference-blue.svg?style=flat-square\" alt=\"GoDoc\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n`evio` is an event loop networking framework that is fast and small. It makes direct [epoll](https://en.wikipedia.org/wiki/Epoll) and [kqueue](https://en.wikipedia.org/wiki/Kqueue) syscalls rather than using the standard Go [net](https://golang.org/pkg/net/) package, and works in a similar manner as [libuv](https://github.com/libuv/libuv) and [libevent](https://github.com/libevent/libevent).\n\nThe goal of this project is to create a server framework for Go that performs on par with [Redis](http://redis.io) and [Haproxy](http://www.haproxy.org) for packet handling. It was built to be the foundation for [Tile38](https://github.com/tidwall/tile38) and a future L7 proxy for Go.\n\n*Please note: Evio should not be considered as a drop-in replacement for the standard Go net or net/http packages.*\n\n## Features\n\n- [Fast](#performance) single-threaded or [multithreaded](#multithreaded) event loop\n- Built-in [load balancing](#load-balancing) options\n- Simple API\n- Low memory usage\n- Supports tcp, [udp](#udp), and unix sockets\n- Allows [multiple network binding](#multiple-addresses) on the same event loop\n- Flexible [ticker](#ticker) event\n- Fallback for non-epoll/kqueue operating systems by simulating events with the [net](https://golang.org/pkg/net/) package\n- [SO_REUSEPORT](#so_reuseport) socket option\n\n## Getting Started\n\n### Installing\n\nTo start using evio, install Go and run `go get`:\n\n```sh\n$ go get -u github.com/tidwall/evio\n```\n\nThis will retrieve the library.\n\n### Usage\n\nStarting a server is easy with `evio`. Just set up your events and pass them to the `Serve` function along with the binding address(es). Each connections is represented as an `evio.Conn` object that is passed to various events to differentiate the clients. At any point you can close a client or shutdown the server by return a `Close` or `Shutdown` action from an event.\n\nExample echo server that binds to port 5000:\n\n```go\npackage main\n\nimport \"github.com/tidwall/evio\"\n\nfunc main() {\n\tvar events evio.Events\n\tevents.Data = func(c evio.Conn, in []byte) (out []byte, action evio.Action) {\n\t\tout = in\n\t\treturn\n\t}\n\tif err := evio.Serve(events, \"tcp://localhost:5000\"); err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n```\n\nHere the only event being used is `Data`, which fires when the server receives input data from a client.\nThe exact same input data is then passed through the output return value, which is then sent back to the client. \n\nConnect to the echo server:\n\n```sh\n$ telnet localhost 5000\n```\n\n### Events\n\nThe event type has a bunch of handy events:\n\n- `Serving` fires when the server is ready to accept new connections.\n- `Opened` fires when a connection has opened.\n- `Closed` fires when a connection has closed.\n- `Detach` fires when a connection has been detached using the `Detach` return action.\n- `Data` fires when the server receives new data from a connection.\n- `Tick` fires immediately after the server starts and will fire again after a specified interval.\n\n### Multiple addresses\n\nA server can bind to multiple addresses and share the same event loop.\n\n```go\nevio.Serve(events, \"tcp://192.168.0.10:5000\", \"unix://socket\")\n```\n\n### Ticker\n\nThe `Tick` event fires ticks at a specified interval. \nThe first tick fires immediately after the `Serving` events.\n\n```go\nevents.Tick = func() (delay time.Duration, action Action){\n\tlog.Printf(\"tick\")\n\tdelay = time.Second\n\treturn\n}\n```\n\n## UDP\n\nThe `Serve` function can bind to UDP addresses. \n\n- All incoming and outgoing packets are not buffered and sent individually.\n- The `Opened` and `Closed` events are not availble for UDP sockets, only the `Data` event.\n\n## Multithreaded\n\nThe `events.NumLoops` options sets the number of loops to use for the server. \nA value greater than 1 will effectively make the server multithreaded for multi-core machines. \nWhich means you must take care when synchonizing memory between event callbacks. \nSetting to 0 or 1 will run the server as single-threaded. \nSetting to -1 will automatically assign this value equal to `runtime.NumProcs()`.\n\n## Load balancing\n\nThe `events.LoadBalance` options sets the load balancing method. \nLoad balancing is always a best effort to attempt to distribute the incoming connections between multiple loops.\nThis option is only available when `events.NumLoops` is set.\n\n- `Random` requests that connections are randomly distributed.\n- `RoundRobin` requests that connections are distributed to a loop in a round-robin fashion.\n- `LeastConnections` assigns the next accepted connection to the loop with the least number of active connections.\n\n## SO_REUSEPORT\n\nServers can utilize the [SO_REUSEPORT](https://lwn.net/Articles/542629/) option which allows multiple sockets on the same host to bind to the same port.\n\nJust provide `reuseport=true` to an address:\n\n```go\nevio.Serve(events, \"tcp://0.0.0.0:1234?reuseport=true\"))\n```\n\n## More examples\n\nPlease check out the [examples](examples) subdirectory for a simplified [redis](examples/redis-server/main.go) clone, an [echo](examples/echo-server/main.go) server, and a very basic [http](examples/http-server/main.go) server.\n\nTo run an example:\n\n```sh\n$ go run examples/http-server/main.go\n$ go run examples/redis-server/main.go\n$ go run examples/echo-server/main.go\n```\n\n## Performance\n\n### Benchmarks\n\nThese benchmarks were run on an ec2 c4.xlarge instance in single-threaded mode (GOMAXPROC=1) over Ipv4 localhost.\nCheck out [benchmarks](benchmarks) for more info.\n\n\u003cimg src=\"benchmarks/out/echo.png\" width=\"336\" height=\"144\" border=\"0\" alt=\"echo benchmark\"\u003e\u003cimg src=\"benchmarks/out/http.png\" width=\"336\" height=\"144\" border=\"0\" alt=\"http benchmark\"\u003e\u003cimg src=\"benchmarks/out/redis_pipeline_1.png\" width=\"336\" height=\"144\" border=\"0\" alt=\"redis 1 benchmark\"\u003e\u003cimg src=\"benchmarks/out/redis_pipeline_8.png\" width=\"336\" height=\"144\" border=\"0\" alt=\"redis 8 benchmark\"\u003e\n\n\n## Contact\n\nJosh Baker [@tidwall](http://twitter.com/tidwall)\n\n## License\n\n`evio` source code is available under the MIT [License](/LICENSE).\n\n","funding_links":[],"categories":["Misc","Go","开源类库","Networking, Distributed, Microservices \u0026 Cloud - Tools \u0026 Services","Open source library","\u003ca name=\"Go\"\u003e\u003c/a\u003eGo"],"sub_categories":["网络","The Internet"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fevio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftidwall%2Fevio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftidwall%2Fevio/lists"}