Files
dsh_ai1net_server/src/net/relay/rendezvous.ts
T
admin 146c3d25ef feat(overlay): 覆盖网络线序①–⑮ 代码与测试产物入库
覆盖网络线累积产物(此前只在工作区、未入版本库):
- 新增 relay 子系统 src/net/relay/**(wire/duplex/server/client/dialer/switcher/directory/identity/keys/placement/network/addr-override/main/index)
- 新增 src/worker/relay-tunnel.ts、src/web/routes/overlay.ts
- 新增观测/演练脚本 overlay-probe、overlay-failover-drill、overlay-keyring、overlay-holepunch、overlay-jitter、overlay-wan、overlay-relaykey-add、relay-mem-calibrate
- 新增测试 12 个(relay / relay-failover / remote-spawner / instance-port / overlay-{network,auth,bootstrap,identity} / remote-user-fs 等)

验收基线:npm test = 162 pass / 0 fail / 1 skip;--scene all = 12 PASS / 0 SKIP / 0 FAIL;overlay-probe = 12/12
2026-09-17 17:03:27 +08:00

58 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* `relay:<id>` —— 会合实现的第三个(也是**去掉 sshd 依赖的那一个**)。
*
* ## 与其他两个实现的关系(同一 `Rendezvous` 接口,可共存、可逐个切换)
* | 实现 | `via` | Manager 侧看到的地址 | 数据面 |
* |---|---|---|---|
* | `LocalRendezvous` | `local` | `127.0.0.1:19100`(同机直连) | 无中转 |
* | `ManagerSshRendezvous` | `manager-ssh` | `127.0.0.1:19000`(**sshd 反向隧道落点**) | Manager 主机上的 sshd |
* | **`RelayRendezvous`** | `relay` | `127.0.0.1:<relay 动态分配>`(**relay 开了回环监听**) | relay 的一条出向 wss |
*
* 三者对 Manager 侧**同形**(都是 `host:port`)⇒ 换实现不动调用方,这是 S0 抽 `Reachability`
* 的全部意义(`src/net/rendezvous.ts:64` 早就写了"本类应被 `relay:<id>` 实现替换")。
*
* ## 独有增益:**实时在线态**
* 前两个实现只能回答"表里写的地址是什么"——`dsh_instances.status` 是 DB 快照,**不实时**。
* relay 的注册由心跳维持(45s 无帧即判死)⇒ 本实现可以**先问在线、再给地址**,
* 离线直接回 `undefined`(让上层回退别的实现,而不是往死地址上打、干等到超时)。
*
* @module dshs/net/relay/rendezvous
*/
import { VIA_RELAY, type Reachability } from '../reachability.js'
import type { AddressLookup, Rendezvous } from '../rendezvous.js'
import { parseLogicalName } from './network.js'
export interface RelayRendezvousOptions {
/** relay 自身的拨号目标(诊断 / 管理面展示用),如 `wss://dsh.alotbuy.com/dshs-relay`。 */
dialTargetUrl: string
/**
* **逻辑名** → `host:port` 的查表函数(会合实现不直接连 DB,与另两个实现一致)。
* 键是逻辑名(P0-3)⇒ 同名 host 分属两张网时各查各的,不会互相覆盖。
*/
addressOf: AddressLookup
/**
* **实时**在线判定(relay 心跳驱动)。省略 = 不判在线(退化成与另两个实现相同的纯查表)。
* 入参同样**逻辑名**(relay 的端点视图按 `network/hostId:port` 建键)。
*/
online?: (name: string) => boolean
}
export class RelayRendezvous implements Rendezvous {
readonly id = VIA_RELAY
constructor(private readonly opts: RelayRendezvousOptions) {}
dialTarget(): string {
return this.opts.dialTargetUrl
}
async resolve(name: string): Promise<Reachability | undefined> {
if (this.opts.online !== undefined && !this.opts.online(name)) return undefined
const address = this.opts.addressOf(name)
if (address === undefined) return undefined
const { network, hostId } = parseLogicalName(name)
return { hostId, networkId: network, via: this.id, address, scheme: 'http' }
}
}