{"id":16652354,"url":"https://github.com/byxor/wsio","last_synced_at":"2025-08-17T14:38:44.685Z","repository":{"id":57552399,"uuid":"153004069","full_name":"byxor/wsio","owner":"byxor","description":"I/O wrappers for gorilla websockets in Go (Reader/Writer implementations)","archived":false,"fork":false,"pushed_at":"2018-10-30T22:53:01.000Z","size":417,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-19T09:28:51.585Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/byxor.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}},"created_at":"2018-10-14T18:12:18.000Z","updated_at":"2020-02-03T14:44:22.000Z","dependencies_parsed_at":"2022-09-26T18:50:41.628Z","dependency_job_id":null,"html_url":"https://github.com/byxor/wsio","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byxor%2Fwsio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byxor%2Fwsio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byxor%2Fwsio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byxor%2Fwsio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/byxor","download_url":"https://codeload.github.com/byxor/wsio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243249816,"owners_count":20260889,"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-10-12T09:28:27.449Z","updated_at":"2025-03-12T16:22:42.676Z","avatar_url":"https://github.com/byxor.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wsio\n\n[I/O](https://golang.org/pkg/io/) helpers to be used alongside [gorilla websockets](https://www.github.com/gorilla/websocket) in Go.\n\n\u003cimg alt=\"Image of wsio\" src=\"https://raw.githubusercontent.com/byxor/wsio/master/docs/wsio.png\" width=30%\u003e\n\n[![Documentation](https://img.shields.io/badge/godoc-reference-5272B4.svg?style=flat-square)](https://godoc.org/github.com/byxor/wsio)\n\n## Includes\n\n* `WebsocketReader` (implements [io.Reader](https://golang.org/pkg/io/#Reader))\n* `WebsocketWriter` (implements [io.Writer](https://golang.org/pkg/io/#Writer))\n\n## Why wsio?\n\n* It allows you to write code that interacts with websockets, without depending on websockets.\n* It increases the testability of your code.\n* It reduces the cost of switching networking implementations.\n\n## Why not wsio?\n\n* You want fine-tuned control over your websocket connections.\n\n## Demo\n\nLet's write an \"echo\" program that reads some input, prefixes it with `\"ECHO: \"`, and echoes it back.\n\nFor now, let's use websockets for our input and output.\n\nHere's some boilerplate to set up an endpoint.\n\n```go\n// package...\n// imports...\n\nvar upgrader = websocket.Upgrader{\n\tCheckOrigin: func(r *http.Request) bool {\n\t\treturn true\n\t},\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/\", echoHandler)\n\tlog.Fatal(http.ListenAndServe(\"localhost:8080\", nil))\n}\n```\n\n### Without wsio\n\n```go\nfunc echoHandler(response http.ResponseWriter, request *http.Request) {\n\tconnection, _ := upgrader.Upgrade(response, request, nil)\n\tdefer connection.Close()\n\n\tfor {\n\t\techo(connection)\n\t}\n}\n\nfunc echo(connection *websocket.Conn) {\n\tmessageType, data, _ := connection.ReadMessage()\n\tmessage := fmt.Sprintf(\"ECHO: %s\", string(data))\n\tconnection.WriteMessage(messageType, []byte(message))\n}\n```\n\n* Our `echo` function has a hardcoded dependency on websockets.\n* We cannot test this function without opening a real connection.\n* We cannot re-use this function for different I/O devices.\n\n### With wsio\n\n```go\nfunc echoHandler(response http.ResponseWriter, request *http.Request) {\n\tconnection, _ := upgrader.Upgrade(response, request, nil)\n\tdefer connection.Close()\n\n\treader := wsio.WebsocketReader{connection}\n\twriter := wsio.WebsocketWriter{connection}\n\n\tfor {\n\t\techo(\u0026reader, \u0026writer)\n\t}\n}\n\nfunc echo(reader io.Reader, writer io.Writer) {\n\tbuffer := make([]byte, 1024)\n\treader.Read(buffer)\n\tmessage := fmt.Sprintf(\"ECHO: %s\", string(buffer))\n\twriter.Write([]byte(message))\n}\n```\n\n* Our `echo` function is device independent.\n* We can unit test this function.\n* We can re-use this function with different I/O devices.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyxor%2Fwsio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyxor%2Fwsio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyxor%2Fwsio/lists"}