Repository navigation
feat: 房间上限 50 人(写死),并让流量随人数合理增长 - #8
Merged
Merged
Conversation
Room files gain a 更换中继 panel that re-emits the same room (master or wrapped key untouched, no password needed) with a new relay list and exact CSP connect-src. The hosted maker converts existing files, and the CLI gains a retarget command. All three paths produce byte-identical output that passes verify-room-file. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
1. Relay-agnostic transport (version 3 rooms)
- Relay entries bc+wss://, nostr+wss://, mqtt+wss:// select version 3;
classic wss:// rooms stay version 2, unchanged. Retarget converts
between them with the same key, password and roomId.
- html-room/mesh.js: members admit (AES-GCM frames under a master-derived
key), number (announce, claim, earliest claim wins), list and attribute
each other; relays only forward. Every frame goes to every relay and is
de-duplicated by IV, so one surviving relay keeps the room together.
- Node server and Cloudflare Worker serve /bc/<topic> plain broadcast.
2. Easier relays
- relay/go: dependency-free Go broadcast relay, one ~6 MB binary for
Windows, macOS, Linux, BSD, Android and OpenWrt routers; -tunnel prints
a public bc+wss:// address via a Cloudflare quick tunnel (no domain,
open port or root).
- scripts/relay-quickstart.sh downloads it (SHA-256 enforced) and
cloudflared; Relay binaries workflow publishes 13 platform builds.
3. External protocols
- Nostr: ephemeral kind 20111 events tagged with the topic, signed with
a per-session BIP-340 key (@noble/curves).
- MQTT 3.1.1 over WebSocket, QoS 0, topic htmlroom/<topic>.
Tests: unit (parsing, sealing, packets, membership clashes), real relays
(Node, Go, signature-checking Nostr relay, aedes MQTT, Worker /bc/ under
wrangler dev), browser end-to-end over four relays with relay loss.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Rewrites every user-facing string in the room creator and the generated index.html in everyday words, moves relay settings into a collapsed section, highlights the main buttons, and links the repository (https://github.com/Freecode100Year/htmlroom.git) from both pages. Tests updated for the new wording. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Files carry an optional custom: true (on by default in the creation page and CLI room; untick or --strict for exact relays only). Such files allow connect-src wss: plus loopback ws, and show a relay box on the entry screen; typed relays apply to that visit only and pick classic or decentralized mode, with the same key, password and roomId. Web links never show the box. Converter and CLI retarget keep or change the setting. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
- Room files fold a creator: a new room with a new key and optional new
password, built offline from the page's own script and style bytes
(htmlFor), byte-identical to a release build.
- A blank file ({} or {relays}) is the creator: the offline generator and
the hosted site. It also opens #hr1= links (CSP wss: + loopback ws) and
converts old files; hosted, it offers itself as an offline download.
- The separate web entry (web.js, hr.js, hr.css) is gone: hr.html and the
Pages index.html are the creator file; _headers is generated with the
same script and style hashes.
Tests: offline chain blank -> A -> B (new password) -> C with no network
requests and release-identical output, chat in B, site self-download;
existing suites updated for links on the site reaching any relay.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Every file carries html-room/serve.js in an HTML comment before the doctype; to Node the page is a block comment, so `node index.html` runs a zero-dependency relay (/hr/ with the shared rules, /bc/, /healthz, --tunnel, --tls-cert). A blank creator also serves itself, making one file a complete site; a room file never serves itself (its key). New files created in the browser carry the server part from document.firstChild. Tests: the shared /hr/ and /bc/ relay probes run against node index.html; browser test serves the site from the file, chats through it, and runs the downloaded room file as a relay. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
- src/limits.js: MAX_MEMBERS = 50, the single source for every relay (Node, Worker, the file's own server, /bc/) and every page; not configurable. - Key wraps go only to their members: key frames carry `to`, relays hand them to those members (hellos still go to all); old relays ignore it. - A page asks again (hello) only the members whose chains are missing, never the whole room on a timer: every hello makes all receivers re-send. - Owed keys are batched for 300 ms; decentralized numbers settle 1.5 s before keys are made, and claims spread over the lowest free numbers. - lib/group.js: learning a member's ML-KEM key for the first time no longer resets a pair secret already received (stalled pairs under targeting). - Relay limits sized for a newcomer's key burst in a full room. Measured with 50 real clients in one process: classic relay, all ready in ~7 s, ~265 KB each (was: relay disconnects at ~600 MB); decentralized /bc/ 20 members ~12 s, ~450 KB each. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
The single-file site no longer ships hr.js/hr.css; the installer's source check and its CI test now use dist/hr.html. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
…cleanup The Windows unit job has stayed in progress since the decentralized relay commit. Background intervals (mesh sweep, relay heartbeat) kept test processes alive when a timing assertion failed before cleanup was wired. Timers are now unref'd (no-op in browsers), test cleanup tolerates early failures, awaited closes time out, and npm test sets --test-timeout. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
URL.pathname gives /D:/... on Windows, so the relay fixtures never started (and the Go build ran in a missing directory). Use fileURLToPath/join and os.tmpdir(); skip the POSIX fake-cloudflared test on Windows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PCUwNSXQdqfDSugmFo4qmM
Freecode100Year
temporarily deployed
to
github-pages
October 30, 2026 00:12 — with
GitHub Actions
Inactive
This was referenced Oct 30, 2026
Merged
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
一个房间最多 50 人,统一写死在代码里(
src/limits.js),所有中继和页面执行同一个数,没有任何配置能改。为什么要优化
用 50 个真实客户端(完整签名、混合加密、ML-KEM)同时进房实测,原有逻辑在约 5 秒内产生约 600 MB 流量,所有人都被中继限流断开。25 人时同样存在这个问题,只是原有测试只有两三个人,没测出来。根因:
改动
MAX_MEMBERS = 50是唯一来源。经典中继(Node、Worker、文件内置服务器)入房、/bc/每个 topic 的连接上限(50+14,留给重连)、页面校验、去中心化编号认领都从这里取。key帧带to,中继只转给这些成员;hello 仍发给所有人。旧中继会忽略to、照常广播,仍然兼容。lib/group.js的一个协议 bug:第一次得知某成员的 ML-KEM 公钥时,不再清空已建立的配对密钥。定向投递下,旧逻辑会让部分成员对永远等待。/bc/10 秒 100 帧。实测(
test/fifty.test.mjs,所有客户端在同一进程,结果偏保守)/bc/(只能广播):HR_MESH_N=50可以跑满员版本。测试
单元测试 78 项、Worker 探针 10 项、9 个浏览器测试和 Pages 测试全部通过;Go 中继通过
go vet。Generated by Claude Code