{"id":13723788,"url":"https://github.com/aglyzov/ws-machine","last_synced_at":"2026-01-06T01:55:44.556Z","repository":{"id":12232165,"uuid":"14842713","full_name":"aglyzov/ws-machine","owner":"aglyzov","description":"WS-Machine is a websocket finite state machine for client websocket connections (Go)","archived":false,"fork":false,"pushed_at":"2017-07-10T07:39:24.000Z","size":19,"stargazers_count":117,"open_issues_count":0,"forks_count":5,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-08-04T01:22:13.366Z","etag":null,"topics":["async","asynchronous","fsm","go","golang","networking","non-blocking","select","state-machine","websocket"],"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/aglyzov.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":"2013-12-01T17:17:40.000Z","updated_at":"2024-05-18T14:41:12.000Z","dependencies_parsed_at":"2022-09-07T11:21:31.065Z","dependency_job_id":null,"html_url":"https://github.com/aglyzov/ws-machine","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/aglyzov%2Fws-machine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aglyzov%2Fws-machine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aglyzov%2Fws-machine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aglyzov%2Fws-machine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aglyzov","download_url":"https://codeload.github.com/aglyzov/ws-machine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224628155,"owners_count":17343282,"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":["async","asynchronous","fsm","go","golang","networking","non-blocking","select","state-machine","websocket"],"created_at":"2024-08-03T01:01:45.686Z","updated_at":"2026-01-06T01:55:44.549Z","avatar_url":"https://github.com/aglyzov.png","language":"Go","funding_links":[],"categories":["Libraries","Go"],"sub_categories":["Go"],"readme":"WS-Machine\n==========\n\n**WS-Machine** is a finite state machine for client websocket connections for [Go](http://golang.org).\nA caller just needs to provide a websocket URL and after that the state machine\ntakes care of the connection. I.e. it connects to the server, reads/writes\nwebsocket messages, keeps the connection alive with pings, reconnects when the\nconnection closes, waits when a connection attempt fails, etc.\n\nMoreover it is fully asynchronous, the caller communicates with a machine via\n4 Go channels:\n\n- `Input` is used to receive `[]byte` messages from a websocket server;\n- `Output` is for sending `[]byte` messages to a websocket server;\n- `Status` lets the user know when the machine state changes;\n- `Command` allows the user to control the state machine.\n\nEvery machine has 4 states:\n\n- `CONNECTING` is when it attempts to connect to a remote server;\n- `CONNECTED` means the connection has been established;\n- `DISCONNECTED` should be obvious;\n- `WAITING` triggers after a failed attempt to connect when the machine makes a pause before the next retry.\n\nBecause everything is done via Go channels it is now possible to integrate\nmultiple websockets with timers, other channes and network connections\nin a single `select` loop. Thus avoiding possible dead-locks, complex logic and\nmaking the code simple, readable, clear and easy to modify/support. As they say **Make websockets great again!**\n\nUnder the hood the library uses [gorilla/websocket](http://github.com/gorilla/websocket) to handle raw websocket connections.\n\nIn order to shutdown a running FSM a user should either close the `Command` channel\nor send the `machine.QUIT` command.\n\nBy default new FSM use the *binary message format* to communicate with a server. Some\nwebsocket server implementations do not support those. In such cases one might switch the machine\nto the *text message format* by sending the `machine.USE_TEXT` command.\n\nExample\n-------\n```go\n// A stateful client for ws://echo.websocket.org\npackage main\n\nimport (\n    \"fmt\"\n    \"net/http\"\n    \"github.com/aglyzov/ws-machine\"\n)\n\nfunc main() {\n\twsm := machine.New(\"ws://echo.websocket.org\", http.Header{})\n\tfmt.Println(\"URL:  \", wsm.URL)\n\n\tloop:\n\tfor {\n\t\tselect {\n\t\tcase st, _ := \u003c-wsm.Status:\n\t\t\tfmt.Println(\"STATE:\", st.State)\n\t\t\tif st.Error != nil {\n\t\t\t\tfmt.Println(st.Error)\n\t\t\t}\n\t\t\tswitch st.State {\n\t\t\tcase machine.CONNECTED:\n\t\t\t\tmsg := \"test message\"\n\t\t\t\twsm.Output \u003c- []byte(msg)\n\t\t\t\tfmt.Println(\"SENT: \", msg)\n\t\t\tcase machine.DISCONNECTED:\n\t\t\t\tbreak loop\n\t\t\t}\n\t\tcase msg, ok := \u003c-wsm.Input:\n\t\t\tif ok {\n\t\t\t\tfmt.Println(\"RECV: \", string(msg))\n\t\t\t\twsm.Command \u003c- machine.QUIT\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nSee more [examples](http://github.com/aglyzov/ws-machine/tree/master/examples).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faglyzov%2Fws-machine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faglyzov%2Fws-machine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faglyzov%2Fws-machine/lists"}