Table of Contents

v0.2.11

EchoHubSpace directory protocol overhaul: authenticated server registration with persistent claim tokens, near-real-time user-count updates, and richer server metadata (tags, multi-host, version). Coordinated cutover with the EchoHubSpace directory deploy.

New Features

  • EchoHubSpace claim-token authentication — the directory issues a per-server claim token on first registration, persisted atomically alongside the SQLite database (chmod 0600 on Unix). Subsequent reconnects authenticate with the token instead of relying on raw hostname-squatting protection. Token survives both client and directory restarts; lost tokens require an admin-side DELETE /api/servers/{id} on the directory to recover
  • Server tags — public servers can advertise topic tags via the new Server:Tags config array, surfacing as filter facets in the EchoHubSpace browser
  • Multi-host advertisement — a single server can register multiple hostnames (e.g. apex domain, IPv6, alias domains) by listing them in Server:PublicHosts. All hosts route to the same directory row
  • Server version sent to directory — the EchoHubSpace browser shows what version each public server is running, pulled from the server's assembly informational version
  • Operator-facing GET /api/server/directory endpoint (Admin role required) — returns ServerId, IsRegistered, LastRegisteredAt, LastError, and any ConflictingHosts for support tickets. Never exposes the claim token itself, only a HasClaimToken boolean

Refactoring

  • Replace 30s polling with event-driven directory updates — PresenceTracker now raises UserCountChanged only when the distinct user count actually changes (multi-tab/multi-connection users no longer trigger). ServerDirectoryService consumes via a single-slot Channel<int> (latest-wins coalesces bursts) with a 1-second min-interval throttle. Directory reflects user-count changes within ~1s instead of up to 30s stale
  • Wrap directory hub responses in a Response<T> envelope with IsSuccess/Data/Errors/Version shape — protocol version is pinned client-side (currently 1.0); mismatches trigger a permanent-failure stop with operator-facing log
  • Stop attempting re-registration after permanent failures (HostAlreadyClaimed, InvalidToken, HostConflict, InvalidInput) — the directory no longer terminates the connection on these errors, so the client suppresses re-register on Reconnected to avoid tight retry loops. Operator must restart the server after fixing config

Configuration

  • Breaking: Server:PublicHost (string) renamed to Server:PublicHosts (string array). Public servers must update appsettings.json — single-host deployments use a one-element array
  • New Server:Tags (string array) — defaults to empty
  • New optional Server:DirectoryClaimPath — overrides the path of the persisted claim file. Defaults to a directory-claim.json next to the SQLite database. Treat the file as a secret; back it up alongside the database