{"id":21393168,"url":"https://github.com/cole-maxwell1/chatroom","last_synced_at":"2026-04-21T05:31:37.536Z","repository":{"id":250371151,"uuid":"834260320","full_name":"cole-maxwell1/chatroom","owner":"cole-maxwell1","description":"Websocket Chatroom","archived":false,"fork":false,"pushed_at":"2024-08-10T20:06:55.000Z","size":149,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T02:48:24.554Z","etag":null,"topics":["go","htmx","templ","websocket"],"latest_commit_sha":null,"homepage":"https://chat.colemaxwell.dev","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cole-maxwell1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-07-26T19:32:45.000Z","updated_at":"2024-08-10T20:06:44.000Z","dependencies_parsed_at":"2025-01-23T01:39:49.665Z","dependency_job_id":null,"html_url":"https://github.com/cole-maxwell1/chatroom","commit_stats":null,"previous_names":["cole-maxwell1/chatroom"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/cole-maxwell1/chatroom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cole-maxwell1%2Fchatroom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cole-maxwell1%2Fchatroom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cole-maxwell1%2Fchatroom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cole-maxwell1%2Fchatroom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cole-maxwell1","download_url":"https://codeload.github.com/cole-maxwell1/chatroom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cole-maxwell1%2Fchatroom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32078737,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T02:38:07.213Z","status":"ssl_error","status_checked_at":"2026-04-21T02:38:06.559Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","htmx","templ","websocket"],"created_at":"2024-11-22T14:09:38.661Z","updated_at":"2026-04-21T05:31:37.522Z","avatar_url":"https://github.com/cole-maxwell1.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chatroom Project\n\nThis project is a chatroom application I threw together to learn more about Websockets, Go channels, and the hot Javascript library of the moment [HTMX](https://htmx.org/). The chatroom allows users to send messages to each other in real-time and see how many other users are connected to the chatroom. The last 100 messages are stored in a ring buffer and displayed to new users when they join the chatroom.\n\n## Concepts Explored\n\n- **Websockets**: Utilizes a *Websocket* to push messages and total connected users to clients in real-time.\n- **Efficient Message Storage**: Implements a [ring buffer](https://en.wikipedia.org/wiki/Circular_buffer) data structure to manage and store chat messages, preventing high memory usage. The application stores the last 100 messages.\n- **Injection Attacks**: Uses the `templ` library to prevent injection attacks in the chatroom.\n- **Javascript Internationalization API**: Utilizes the [Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) to format dates and times in the chatroom.\n- **Go Channels**: This server makes heavy use of Go channels to manage the communication between the server and clients. All sends and receives are done through channels and a central broker to prevent blocks and slow delivery to other connected clients.\n\n## Usage\n\n 1. You can pull down the published docker image and give it a try yourself:\n    ```sh\n    docker run -d -p 8080:8080 ghcr.io/cole-maxwell1/chatroom:latest\n    ```\n 1. Or view live at [chat.colemaxwell.dev](https://chat.colemaxwell.dev/)\n\n## K6 Load Testing\n\nI ran some load testing on the chatroom using the [K6](https://grafana.com/docs/k6/latest/get-started/) load testing tool. The test ramps to 50 users over 30 seconds and sustains 50 for one minute. Each connection sends a message after connecting. The test was run on a Hetzner VPS with 2 vCPUs and 2GB of RAM. `loadtest.js` is configured to run on a local instance. You can run the test yourself with the following command:\n```sh\nk6 run loadtest.js\n```\n\nResults:\n```sh\n✓ Connected successfully\n\n     checks................: 100.00% ✓ 3316        ✗ 0\n     data_received.........: 165 MB  1.6 MB/s\n     data_sent.............: 2.6 MB  26 kB/s\n     iteration_duration....: avg=1.21s    min=1.14s    med=1.16s    max=2.55s p(90)=1.35s    p(95)=1.45s\n     iterations............: 3316    32.915225/s\n     vus...................: 4       min=2         max=50\n     vus_max...............: 50      min=50        max=50\n     ws_connecting.........: avg=209.99ms min=139.68ms med=162.28ms max=1.53s p(90)=348.65ms p(95)=451.28ms\n     ws_msgs_received......: 343532  3409.961751/s\n     ws_msgs_sent..........: 3316    32.915225/s\n     ws_session_duration...: avg=1.21s    min=1.14s    med=1.16s    max=2.55s p(90)=1.35s    p(95)=1.45s\n     ws_sessions...........: 3316    32.915225/s\n\n\nrunning (1m40.7s), 00/50 VUs, 3316 complete and 0 interrupted iterations\ndefault ✓ [======================================] 00/50 VUs  1m40s\n```\n\n## Development\n\n1. **Clone the Repository**:\n    ```sh\n    git clone https://github.com/cole-maxwell1/chatroom.git \u0026\u0026 cd chatroom\n    ```\n\n1. **Install Dependencies**:\n    ```sh\n    npm install\n    ```\n\n1. **Build the Project**:\n    ```sh\n    make build\n    ```\n\n1. **Run the Server**:\n    ```sh\n    make run\n    ```\n\n## Injection Attacks\nOne of the big reasons for using the `templ` library is to prevent injection attacks in the chatroom. The `templ` library has some nice built checks to prevent this. For example, the `templ` library will not allow the use of the `\u003cscript\u003e` tag in the chatroom. Don't believe me? Try it out for yourself!\n```html\n\u003cscript\u003e \n    body.addEventListener('htmx:wsBeforeMessage'\n    function (event) { console.log('Nasty code was run'); document.getElementById('status').innerText = 'Nasty code was run!!!'; }); \n\u003c/script\u003e\n```\n\n## HTMX Takeaways\nI really enjoyed getting a little closer to the DOM and using HTMX. The web sockets extension was really easy to work with. I'd like to seem the HTMX team add some additional documentation on what [websocket close codes](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code) the automatic reconnect feature will work on, for the record it's only codes `1006, 1012, 1013` that reconnect automatically. There was some learning curve with the client side date formatting, but I was able to get it working using the `htmx:oobBeforeSwap` event, which wasn't well documented. The nice thing about using a small library like HTMX is that it's actually easy to read the source code and figure out what it's doing and how to use it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcole-maxwell1%2Fchatroom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcole-maxwell1%2Fchatroom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcole-maxwell1%2Fchatroom/lists"}