{"id":15567629,"url":"https://github.com/purehyperbole/wsev","last_synced_at":"2026-01-24T04:03:20.477Z","repository":{"id":206534967,"uuid":"717111493","full_name":"purehyperbole/wsev","owner":"purehyperbole","description":"An ergonomic epoll based websocket server library in Go","archived":false,"fork":false,"pushed_at":"2024-10-22T19:06:39.000Z","size":97,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-24T00:04:12.210Z","etag":null,"topics":["epoll","golang","library","websocket","websocket-server"],"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/purehyperbole.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":"2023-11-10T15:27:01.000Z","updated_at":"2025-03-30T20:34:33.000Z","dependencies_parsed_at":"2024-01-19T15:47:37.512Z","dependency_job_id":"8cb73c44-3055-40e4-bc73-1fcdb8fe0cc2","html_url":"https://github.com/purehyperbole/wsev","commit_stats":null,"previous_names":["purehyperbole/wsev"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purehyperbole%2Fwsev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purehyperbole%2Fwsev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purehyperbole%2Fwsev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/purehyperbole%2Fwsev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/purehyperbole","download_url":"https://codeload.github.com/purehyperbole/wsev/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250535098,"owners_count":21446508,"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":["epoll","golang","library","websocket","websocket-server"],"created_at":"2024-10-02T17:12:05.685Z","updated_at":"2026-01-24T04:03:20.381Z","avatar_url":"https://github.com/purehyperbole.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wsev [![Go Reference](https://pkg.go.dev/badge/github.com/purehyperbole/wsev.svg)](https://pkg.go.dev/github.com/purehyperbole/wsev) [![Go Report Card](https://goreportcard.com/badge/github.com/purehyperbole/wsev)](https://goreportcard.com/report/github.com/purehyperbole/wsev) ![Build Status](https://github.com/purehyperbole/wsev/actions/workflows/ci.yml/badge.svg)\n\n\nAn event based websocket server implementation based on epoll, designed for ease of use and high connection concurrency.\n\nSome parts for reading and writing websocket headers have been derrvied from the excellent [github.com/gobwas/ws](https://github.com/gobwas/ws) and lightly modified to support buffer reuse.\n\n## Features\n\n- [x] Epoll based websocket handler\n- [x] SO_REUSEPORT for multiple epoll listeners on the same port\n- [x] Pooled write buffers for efficient memory usage\n- [x] Passes the [autobahn testsuite](https://github.com/crossbario/autobahn-testsuite)\n- [x] Only depends on `golang.org/x/sys`\n- [x] Detect connection timeouts\n\n## Setup\n\n```sh\ngo get github.com/purehyperbole/wsev\n```\n\n## Usage\n\n```go\npackage main\n\nimport (\n    \"log\"\n    \"runtime\"\n\n    \"github.com/purehyperbole/wsev\"\n)\n\nfunc main() {\n    h := \u0026wsev.Handler{\n        OnConnect: func(conn *wsev.Conn) {\n            // client has connected\n        },\n        OnDisconnect: func(conn *wsev.Conn, err error) {\n            // client has disconnected\n        },\n        OnPing: func(conn *wsev.Conn) {\n            // client has sent pong\n        },\n        OnMessage: func(conn *wsev.Conn, msg []byte) {\n            // client has sent a binary/text event\n        },\n        OnError: func(err error, isFatal bool) {\n            // server has experienced an error\n        }\n    }\n\n    // will start a new websocket server on port 9000\n    err := wsev.New(\n        h, \n        // the number of listener goroutines that will be started\n        // defaults to GOMAXPROCS\n        wsev.WithListeners(count int),\n        // the deadline that used when reading from sockets that have data\n        wsev.WithReadDeadline(time.Millisecond*100),\n        // the deadline that data will be flushed to the underlying connection \n        // when the data in the buffer has not exceeded the buffer size\n        wsev.WithWriteBufferDeadline(time.Millisecond * 100),\n        // the size of the write buffer for a connection. these buffers are \n        // only allocated and used when there is data ready for writing to\n        // the connection. Once the buffer has been flushed, the buffer is\n        // returned to a pool for reuse. \n        wsev.WithWriteBufferSize(1\u003c\u003c14),\n        // sets the size of the read buffer for reading from the connection.\n        // a read buffer is allocated per event loop\n        wsev.WithReadBufferSize(1\u003c\u003c14),\n    ).Serve(9000)\n\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    runtime.Goexit()\n}\n```\n\n## Example - Chat Room\n\n```go\npackage main\n\nimport (\n    \"io\"\n    \"log\"\n    \"net\"\n    \"runtime\"\n    \"sync\"\n\n    \"github.com/purehyperbole/wsev\"\n)\n\nfunc main() {\n    // keep a list of all connected members\n    var connections []io.Writer\n    var lock sync.Mutex\n\n    h := \u0026wsev.Handler{\n        OnConnect: func(conn *wsev.Conn) {\n            // client has connected, so add it to the list\n            lock.Lock()\n            defer lock.Unlock()\n\n            connections = append(connections, conn)\n        },\n        OnDisconnect: func(conn *wsev.Conn, err error) {\n            // client has disconnected, so remove it from the list\n            lock.Lock()\n            defer lock.Unlock()\n\n            for i := len(connections) - 1; i \u003e= 0; i-- {\n                if connections[i] == conn {\n                    connections = append(connections[:i], connections[i+1:]...)\n                }\n            }\n        },\n        OnMessage: func(conn *wsev.Conn, msg []byte) {\n            // a message has been recevied, broadcast it to the other connections\n            lock.Lock()\n            defer lock.Unlock()\n\n            _, err := io.MultiWriter(connections...).Write(msg)\n            if err != nil {\n            \tlog.Printf(\"failed to write to connections: %s\", err.Error())\n            }\n        },\n    }\n\n    err := wsev.New(\n        h, \n    ).Serve(8000)\n\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    runtime.Goexit()\n}\n```\n\n## Development\n\nRunning tests:\n\n```go\ngo test -v -race\n```\n\nRunning with autobahn testsuite (requires [Docker](https://www.docker.com/))\n\n```go\nAUTOBAHN=1 go test -v -race\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurehyperbole%2Fwsev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpurehyperbole%2Fwsev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpurehyperbole%2Fwsev/lists"}