{"id":20791317,"url":"https://github.com/theprofs/socket-identity-playground","last_synced_at":"2026-05-22T03:04:39.538Z","repository":{"id":46026169,"uuid":"429430968","full_name":"TheProfs/socket-identity-playground","owner":"TheProfs","description":"Socket.io identity playground","archived":false,"fork":false,"pushed_at":"2021-11-23T10:12:39.000Z","size":101,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-18T10:44:51.186Z","etag":null,"topics":["identity","socket-io"],"latest_commit_sha":null,"homepage":"https://socket-identity-playground.herokuapp.com/","language":"HTML","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/TheProfs.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":"2021-11-18T12:59:41.000Z","updated_at":"2021-11-23T10:12:42.000Z","dependencies_parsed_at":"2022-09-14T11:12:56.368Z","dependency_job_id":null,"html_url":"https://github.com/TheProfs/socket-identity-playground","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/TheProfs%2Fsocket-identity-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheProfs%2Fsocket-identity-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheProfs%2Fsocket-identity-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheProfs%2Fsocket-identity-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheProfs","download_url":"https://codeload.github.com/TheProfs/socket-identity-playground/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243136238,"owners_count":20241988,"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":["identity","socket-io"],"created_at":"2024-11-17T15:43:14.621Z","updated_at":"2025-12-27T06:33:54.366Z","avatar_url":"https://github.com/TheProfs.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# socket-identity-playground\nsocket.io identity playground\n\nExperiment with ability to fetch room users with user IDs in\na [horizontally scalable, multi-node socket.io setup][socket.io-multiple-nodes]\n\n## Install\n\n```bash\n# Install deps:\n$ npm install\n\n# Install PM2, we need to run socket.io servers in cluster mode:\n$ npm install pm2@latest -g\n```\n\n## Run local\n\nRequirements before running:\n\n- A [Redis][redis] instance is running on `redis://127.0.0.1:6379`\n- You use [NodeJS][nodejs] v14+\n\n```bash\n# Migrate \u0026 seed SQLite3 DB:\n$ npm run reset-db-dev\n\n# Run socket.io server as a 4 node cluster using PM2 and stream logs:\n$ npm run stop-dev \u0026\u0026 npm run start-dev \u0026\u0026 pm2 logs --merge-logs\n\n# Stop socket.io server (kill all nodes):\n$ npm run stop-dev\n\n# Reset database and restart cluster:\n$ npm run reset-db-dev \u0026\u0026 npm run stop-dev \u0026\u0026 npm run start-dev \u0026\u0026 pm2 logs --merge-logs\n```\n\nthen visit:\n\nhttps://localhost:5009/ui/Maths?id_user=1\n\nwhich will create a socket.io client as `id_user: '1'` and join room `\"Maths\"`\nfor example.\n\n## Run on Heroku\n\nThis service is also running on [Heroku][heroku], available at: https://socket-identity-playground.herokuapp.com/\n\nPushing to `main` branch triggers a Heroku build.\n\n### Heroku scripts\n\n```bash\n# Migrate/seed Heroku DB\n$ heroku run npm run reset-db-staging -a socket-identity-playground\n```\n\n### Available users\n\nYou *must* use one of the following `id_user` when visiting a room:\n\n| id_user | name      |\n|---------|-----------|\n| 1       | John      |\n| 2       | Mary      |\n| 3       | Mike      |\n| 4       | Frank     |\n| 5       | Stephanie |\n| 6       | Richard   |\n| 7       | Sonia     |\n| 8       | Charlie   |\n| 9       | Rowan     |\n| 10      | Victoria  |\n\nYou can join any room you want.\n\n## How it works\n\nThe client passes an `id_user` when connecting with a node.\nThe node, saves that value as a property of the socket, like so:\n\n```js\n// server\nio.on('connection', socket =\u003e {\n  socket.id_user = socket.handshake.query.id_user\n})\n```\n\nThe service exposes a REST endpoint, `GET: /:room/users`.\nWhen pinged:\n\n- `GET` request lands on a node, we'll call it the **request node**.\n- The **request node** then finds out all the `socket ids` for that room.\n- For each `id_socket`:\n  - Asks **all other nodes** if they have in their state a `socket` with\n    that `id_socket`.\n    If yes, the **other node** responds with the `socket.id_user` of the\n    found `socket`.\n- The **request node** responds to the `GET` request with a user list,\n  each user containing a `id_socket` and an `id_user` like so:\n\n```js\n  // Room \"Maths\":\n  [\n    { id_socket: '70tSKzb9gzWwfL', id_user: 'foo' },\n    { id_socket: '62sGlHCfUDdmAA', id_user: 'bar' }\n  ]\n```\n\n![GET /:room/users architecture](https://i.ibb.co/YRgbPsT/Screenshot-2021-11-19-at-12-16-34-PM.png)\n\n- The client is then responsible for hydrating the `id_user`s with the full\n  user objects.\n- When a client updates his identity info, he then broadcasts an\n  `identity-change` event.\n- Each participant in the room then rehydrates the user object for the `id_user`  \n  that emitted the `identity-change`.\n\n### Notes:\n\n- We don't create additional state. Each node already has a state, the `io`\n  object which keeps track of all connected `sockets` to that node.\n  We simply add an additional property, `id_user` to each `socket`.\n- Nodes do not actually directly communicate with each other.\n  Communication between nodes happens using the [`customRequest` mechanism][socketio-custom-request],\n  which uses [Redis Pub/Sub][redis-pubsub].\n\n## Authors\n\nThe Profs\n\n## License\n\nThe MIT License\n\n[nodejs]: https://nodejs.org/en/\n[socket.io-multiple-nodes]: https://socket.io/docs/v3/using-multiple-nodes/\n[redis]: https://redis.io/\n[redis-pubsub]: https://redis.io/topics/pubsub\n[socketio-custom-request]: https://github.com/socketio/socket.io-redis-adapter/tree/01028d03dbdc9cc05c940a2ac6bc367119165c16#redisadaptercustomrequestdataobject-fnfunction\n[heroku]: https://heroku.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheprofs%2Fsocket-identity-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheprofs%2Fsocket-identity-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheprofs%2Fsocket-identity-playground/lists"}