{"id":13564042,"url":"https://github.com/markdingo/go-websocket-demo","last_synced_at":"2025-04-03T20:32:45.707Z","repository":{"id":152467536,"uuid":"380945385","full_name":"markdingo/go-websocket-demo","owner":"markdingo","description":"Demo go code showing a simple websocket client connecting to a simple websocket server","archived":false,"fork":false,"pushed_at":"2023-06-19T00:07:06.000Z","size":40,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-08-01T13:30:42.209Z","etag":null,"topics":["go","websocket-client","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":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markdingo.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}},"created_at":"2021-06-28T07:34:00.000Z","updated_at":"2023-03-24T02:39:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"9de3f682-cb63-402f-ae30-1d7e21b282c9","html_url":"https://github.com/markdingo/go-websocket-demo","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/markdingo%2Fgo-websocket-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fgo-websocket-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fgo-websocket-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fgo-websocket-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markdingo","download_url":"https://codeload.github.com/markdingo/go-websocket-demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223030856,"owners_count":17076515,"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":["go","websocket-client","websocket-server"],"created_at":"2024-08-01T13:01:25.875Z","updated_at":"2024-11-04T16:31:43.860Z","avatar_url":"https://github.com/markdingo.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# go-websocket-demo\n\n### Introduction\n\nDemo go code showing a simple websocket client connecting to a simple websocket server\nasking for a feed of stock ticker changes using the recommended\n[nhooyr.io/websocket](https://nhooyr.io/websocket) package.\n\nThe server maintains the websocket connection so long as the client periodically sends\nPing messages indicating responsiveness. Similarly the client maintains the connection so\nlong as the server responds with a Pong message indicating the server is also\nresponsive. In other words: clients know when servers become unresponsive and vice versa\nand thus both sides can release resources and retry as appropriate.\n\nNote that the Ping/Pong messages are application-level messages rather than the intrinsic\nmessage types available within most websocket packages. The reason for this, in part, is\nthat the recommended websocket package only exposed Ping, but not Pong (rather odd - but\nan issue has been raised, so maybe that will change one day). Point being that that makes\na server incapable of determining whether a client is still responsive or not. Sure, the\nclient can tell if the server is unresponsive, but that's only half the story. In our\nscenario it's important for the server to know when a client is unresponsive so it doesn't\ncontinue to consume resources unnecessarily.\n\nThe second reason for using application-level Pings is to demonstrate message demuxing\nwith json as the serialization format. This is not an overly complex problem but there are\nnuances due to the nature of go and the requirements of the\n[encoding/json](https://golang.org/pkg/encoding/json/) package. In short, if you just\nexchange pure json you need to construct the message struct before you know the message\ntype... Thus the exchanged messages include struct identifiers. More details can be found\nin [protocol.go](https://github.com/markdingo/go-websocket-demo/blob/main/protocol.go).\n\n### Purpose\n\nThe main goal of this package is to demonstrate a performant and responsive websocket\nserver implemented in go. At the time of writing the whole system including client, server\nand support modules adds up to approximately 400 executable lines of code yet the server\nefficiently handles multiple clients, includes an extensible framework which allows the\neasy addition of new message types and actively deals with unresponsive clients.\n\n### Caveat Emptor\n\nThis code is demo quality only: there is no client authentication by the server; there are\nno units tests and this code has never been used in earnest.\n\n### How to use\n\nAssuming a Unix platform:\n\n1. Try `git clone git@github.com:markdingo/go-websocket-demo.git`\n\n1. Or if the repo is public try `go get -u github.com/markdingo/go-websocket-demo`\n\n1. Build the client and server with `'make'`\n\n1. Run `'./server localhost:8080'` in one terminal\n\n1. Run `'./client ws://localhost:8080 AAPL SPY'` in another terminal\n\n1. Repeat the previous step as many times as you wish in a new terminal to create a swarm\nof clients. The server should easily handle 100s if not 1000s of clients.\n\n1. If you wait for over a minute you'll see the client exchange Ping messages with the server\nand print the latency of that message exchange\n\n1. Simulate a stalled server by typing `^Z` in the server terminal and watch the clients\neventually determine that the server is unresponsive and attempt reconnections. The Ping\ntimeout is set to one minute so clients will notice an unresponsive server within two\nminutes. Modify\n[config.go](https://github.com/markdingo/go-websocket-demo/blob/main/config.go) if you\nwant to change this or other timeout values.\n\n1. Revivify the server by typing `fg` in the server terminal and watch the clients\nautomatically re-connect and continue receiving stock symbol notifications\n\n1. Do the same thing with the clients: `^Z` to stall them, then watch the server\nultimately discard unresponsive clients. Then `fg` the client and watch it reconnect\nand resume getting ticker notifications.\n\n### Runs on?\n\nThis demo is know to work on Linux, FreeBSD and macOS using go1.16 or later.\n\n**--**\n\n### Copyright and License\n\ngo-websocket-demo is Copyright :copyright: 2021 Mark Delany. This software is licensed\nunder the BSD 2-Clause \"Simplified\" License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkdingo%2Fgo-websocket-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkdingo%2Fgo-websocket-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkdingo%2Fgo-websocket-demo/lists"}