{"id":22870000,"url":"https://github.com/mattdeboard/node-telnet-chat","last_synced_at":"2025-08-09T05:17:16.789Z","repository":{"id":266358740,"uuid":"897621454","full_name":"mattdeboard/node-telnet-chat","owner":"mattdeboard","description":"Node+Telnet chat server with users and rooms","archived":false,"fork":false,"pushed_at":"2025-01-03T20:07:17.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-04T13:47:24.180Z","etag":null,"topics":["chat","chat-application","nodejs","telnet","telnet-server","telnetlib"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/mattdeboard.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-12-03T00:13:56.000Z","updated_at":"2025-01-03T20:07:20.000Z","dependencies_parsed_at":"2025-02-06T16:49:21.569Z","dependency_job_id":"2dda7873-3115-42be-b769-b9bcfb4a72d0","html_url":"https://github.com/mattdeboard/node-telnet-chat","commit_stats":null,"previous_names":["mattdeboard/node-telnet-chat"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mattdeboard/node-telnet-chat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdeboard%2Fnode-telnet-chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdeboard%2Fnode-telnet-chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdeboard%2Fnode-telnet-chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdeboard%2Fnode-telnet-chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattdeboard","download_url":"https://codeload.github.com/mattdeboard/node-telnet-chat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdeboard%2Fnode-telnet-chat/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269532365,"owners_count":24433271,"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","status":"online","status_checked_at":"2025-08-09T02:00:10.424Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["chat","chat-application","nodejs","telnet","telnet-server","telnetlib"],"created_at":"2024-12-13T13:13:18.170Z","updated_at":"2025-08-09T05:17:16.732Z","avatar_url":"https://github.com/mattdeboard.png","language":"TypeScript","readme":"# node-telnet-chat\n\nThis repository contains a multi-user chat server with support for rooms\nbuilt on top of the telnet protocol.\n\nWe leverage the [`telnetlib`](https://www.npmjs.com/package/telnetlib)\nlibrary to handle the Telnet protocol details. It provides an\nimplementation of Node's\n[`net.Server`](https://nodejs.org/api/net.html#class-netserver) TCP\nserver that understands Telnet datagrams.\n\n## Getting Started\n\n```bash\nnpm i\nnpm run dev\n```\n\n## Server Loop\n\nAll of this should be fairly obvious while reading the code, but in the\ninterest of looking out for my future-self, who will absolutely have\nforgotten about every detail of writing this, I think it's valuable to\nlay this out explicitly in prose.\n\n### Order of Events\n\nAt a high level, event handlers are attached to the socket object in the\nfollowing order at request-time:\n\n1. `negotiated`\n2. `username set`\n3. `client constructed`\n\n#### `negotiated`\n\nWhen a client connects to the server, `telnetlib` handles all the\n[connection\nnegotiation](https://www.omnisecu.com/tcpip/telnet-negotiation.php).\nOnce it does that, it\n[emits](https://github.com/cadpnq/telnetlib/blob/5ee49b73bdde7cd77064c3797778d9087ab9ef5f/src/TelnetSocket/TelnetSocket.js#L298)\nthe  `negotiated` signal.\n\nIn this listener, we handle that signal by displaying a welcome message\nand prompt the user to enter a unique username.\n\nOnce the user does so, `username set` is emitted with the validated\nusername as the payload.\n\n#### `username set`\n\nIn this listener, we use the username to construct the `Client` object\nwe'll be storing in memory. We then display some additional\ninfo/instructions to the user.\n\nOnce all that has been written, we emit the `client constructed` event\nwith the `Client` object as the payload.\n\n#### `client constructed`\n\nOnce we have the client, we attach our listeners for `data` (i.e.\nhandling user input) and `end` (handling user disconnection).\n\n## Architecture\n\nThe server is built around two main concepts:\n\n- [`Client`](./src/client.ts): The `Client` class closes over the logic\n  for handling any action a user can do, such as creating or leaving a\n  room. It is also responsible for sending feedback messages over the\n  socket to the user when they perform an action.\n- [`Room`](./src/room.ts): The `Room` class is responsible for both\n  broadcasting chat messages to other users, as well as writing chat\n  logs to disk every so often.\n\n### Client\n\nWhen a new telnet client connects to the server, a `Client` class is\ninstantiated and stored in memory in the\n[`ALL_CLIENTS`](https://github.com/mattdeboard/node-telnet-chat/blob/93778457dfa68cf96f1cc45dba66b5df2906649f/src/index.ts#L32)\nmap. This map maps usernames to clients.\n\nThe client has a handle on the telnet socket. It uses this to send\nfeedback messages to the end user, such as success messages when the\nuser creates a room.\n\nThe client also has the concept of the [\"current\nroom.\"](https://github.com/mattdeboard/node-telnet-chat/blob/776cddb64f099cbafb6dd622b42b51ca67992626/src/client.ts#L6)\nThis is a handle on a `Room` object. The user can only chat in, change\nthe topic of, etc., the \"current room.\"\n\nAdditionally, the client tracks all the rooms in which it is a member.\nThe client will receive messages from any room it's a member of, even if\nit's not the \"current room.\"\n\n### Room\n\nEach room, of course, tracks all the clients \"in\" the room. Being \"in the\nroom\" means that the user will receive messages sent by other users to\nthat room.\n\nEach room will also log the chat to disk. This is currently just bare\nminimum, very primitive implementation of logging. It's not being used\nfor anything, but was rather an exercise in making it work.\n\nOn process termination, any outstanding logs in memory are synchronously\nflushed to disk.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattdeboard%2Fnode-telnet-chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattdeboard%2Fnode-telnet-chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattdeboard%2Fnode-telnet-chat/lists"}