Skip to content

Repository files navigation

TopoSmith — 拓扑匠

浏览器内的网络拓扑绘制与连通性推演器
手动画拓扑 → 精细标注端口速率与线缆类型 → 让工具回答通不通、走哪条路、能跑多快、域名怎么解析过去,并给出为什么

在线试用https://crequency.github.io/TopoSmith/ (纯静态站点,由 GitHub Pages 托管;打开即用,数据只存在浏览器本地)

CI License: MIT Tests Build size TypeScript strict No backend Status: M0

TopoSmith 界面:小微企业办公网预置场景,正在推演一台设计工作站到业务服务器的可达性
预置场景「小微企业办公网」:三个 VLAN 分段 + 机柜上架;图中正在推演 设计工作站 → 业务服务器 的跨 VLAN 可达性(3 跳可达,瓶颈 1 Gbps)。

这是什么

TopoSmith 不是逐包网络仿真器,而是确定性推演器:从拓扑与配置出发,用图算法 + 约束求解 算出路径、可达性、带宽与 DNS 解析链,并输出完整证据链 —— 不只回答"通不通",还回答"为什么"。

  • ✅ 纯前端、零后端,构建产物是纯静态文件
  • ✅ 线缆类型/长度与端口介质/速率参与计算,不是装饰字段
  • ✅ 结果确定可复现:同输入同输出,推演内核里没有随机数与时钟
  • ❌ 不做逐包仿真、不跑真实设备镜像、不提供 CLI —— 理由见 docs/00-overview.md §2/§5

功能

绘制与编辑

  • 设备目录拖放;端口画在设备面板上(网口 / 光口 / PON / 天线按介质绘制),点端口即编辑详情
  • 端口到端口的电缆曲线:连线从端口出发,线缆类型与长度参与协商
  • 端口可增删;卡片宽度可调;机柜容器(8–48U 上架下架、翻转看背面、悬浮透视)
  • 链路聚合:同一对设备之间的并联线缆可标为 LACP 聚合组 ——「双上行冗余」与「插了两根线的环路」从此是两件事
  • 框选与 Ctrl/Shift 多选;六向对齐 + 两轴等距分布;网格与节点吸附(带引导线)
  • 撤销重做(含拖动事务合并)、导入导出、节点树(搜索 / 排序 / 双击定位)
  • 侧栏页面可排版:左侧栏用页签切换「设备目录 / 节点树」,右侧栏把「检查器 / 诊断」上下堆叠、高度可拖;页面可拖到另一侧栏,两侧侧栏宽度可拖(都会记住)
  • 命令菜单 Ctrl/Cmd+Shift+P:VSCode 习惯的面板(搜索 / 分组 / 键盘导航);当前只有界面,命令尚未接入

推演与诊断(四类,全部带证据链)

  • 可达性:能不能通,不通卡在哪一跳、原因码是什么
  • 数据包链路:逐跳列出设备、端口、链路速率、VLAN 与地址
  • 通讯速度:端到端瓶颈在哪一段、单向时延、单流有效吞吐
  • DNS 解析路径:域名 → 哪台服务器 → 缓存命中 / 转发 / NXDOMAIN
  • 二层环路 / 广播风暴:成环时点名闭合的环路径,说明广播帧为什么不会自己消失,并声明哪些结论因此不可信

可视化

  • 诊断后播放流向动画:粒子速度按链路速率对数映射、逐跳停顿、失败停在阻断点并红脉冲
  • 连线与速率标签按带宽着色(1G 红 → 10G 绿,对数均匀分配,右上角图例)
  • 拖设备时连线有平面物理摆动(位移冲量 + 弹簧回零),快甩甩得远、松手回摆几下
  • 适应视图按真实画布尺寸把「设备 ∪ 连线」完整装入;缩放 5%–400%;低缩放自动分级绘制

快速开始

需要 Node ≥ 20 与 pnpm 11。

pnpm install
pnpm dev          # 开发服务器 http://127.0.0.1:31006
pnpm check        # 类型检查 + 两套单测
pnpm build        # 生产构建到 apps/web/dist
pnpm preview      # 预览构建产物

pnpm screenshot / pnpm brand(重新生成 README 主图与 favicon)需要 Playwright 的 Chromium。 开发环境、命令清单、代码约定与提交习惯见 CONTRIBUTING.md

部署

产物是纯静态文件,丢到任意静态服务器即可(挂到子路径时必须带基路径,否则白屏):

BASE_PATH=/TopoSmith/ pnpm build                   # 子路径构建
docker build -t toposmith . && docker run --rm -p 41006:41006 toposmith

容器端口、compose 用法、缓存策略与容器里踩过的坑:见 docs/09-deployment.md

预置场景

工具栏「预置场景」打开选择弹窗,七套开箱可用、且各自演示一类能力的拓扑:

场景 规模 演示什么 有意留的坑
家庭网络 10 台 · 9 线 光猫路由模式做 NAT/DHCP、AP 无线、PON 接入、DNS 转发链
小微企业办公网 15 台 · 15 线 VLAN 分段(办公/访客/服务器)、跨 VLAN 路由、机柜上架 访客段上联口忘打标,ping 摄像机会报「两端不在同一广播域」并指名两个端口
机房机柜 12 台 · 12 线 42U 机柜与多 U 上架、背面端口透视、万兆 DAC、瓶颈定位
光接入 10 台 · 9 线 同一 OLT 两户:桥接光猫 + 自备路由 vs 路由光猫一台搞定 B 户老光猫是 EPON 1G,那条 PON 按 1G 协商
园区无线 13 台 · 12 线 三台 AP 同 SSID、2.4G/5G/6G 速率按两端取小、无线共享介质 一台平板配错 SSID,链路起不来并报 SSID 不一致
网络环路与广播风暴 17 台 · 20 线 三处典型成环(双上行没做聚合 / 跳线插回自己 / 无线中继接回有线)+ 用另一个 VLAN 当对照组 三处环都能修:标成链路聚合或拆掉冗余线、拔掉自环跳线、撤掉无线中继
中型托管 IDC 810 台 · 809 线 3 机房 × 24 柜 × 42U 满配、双千兆 LACP 聚合上联 → 汇聚 → 万兆核心 → 出口;兼作规模压测

每套场景都是自洽的地址规划,并被单测逐条验证「说明里承诺的行为真的成立」,包括"把坑修好后恢复连通"。

推演内核:Anvil

界面之下是一个独立、确定性的推演内核 —— Anvil(铁砧):同一份拓扑与配置,永远得到同一个结论。 它不是逐包仿真器,不发一个包、不跑设备镜像,而是用图算法与约束求解算出结论并给出证据链。

包名 @toposmith/anvil(源码在 packages/engine/
依赖方向 apps/web → @toposmith/anvil → @toposmith/catalog → @toposmith/schema,反向零依赖
运行环境 纯 TypeScript:零 DOM、零 React、零浏览器 API,单测直接在 Node 下跑
负责 链路协商、广播域(VLAN)、路由与 NAT、DHCP 租约、DNS 解析链、二层环路检测、四类诊断
不负责 像素、相机、事件、存储 —— 画布连"能不能连这条线"都要问它(negotiateLink
import { buildWorld, ping } from '@toposmith/anvil';

const world = buildWorld(scenario);            // 纯数据进:派生世界(链路协商 / 地址 / 租约 / 环路)
const result = ping(world, 'dev-pc', '203.0.113.10');

result.ok;                                     // 能不能通
result.steps.map((step) => step.code);         // ['SRC_ADDRESS', 'ROUTE_MATCH', 'ARP_OK', 'REACHED']

设计细节见 docs/05-engine.md,命名与边界的取舍见 docs/DECISIONS.md D-54。

项目结构

toposmith/
├─ docs/                需求 / 领域模型 / 目录 / 架构 / 内核 / 诊断 / 部署 / 路线图 / 决策记录
├─ packages/
│  ├─ schema/           类型定义 + 导入校验(输入契约)
│  ├─ catalog/          设备 / 端口 / 线缆 / 速率目录(纯数据)
│  └─ engine/           推演内核 Anvil(纯 TS,零 DOM/React,可在 Node 下直接测试)
├─ apps/web/            React 19 + Vite 8 + Tailwind 4 + zustand(样式全部内联类名)
├─ Dockerfile + Caddyfile + docker-compose.yml    容器形态(见 docs/09)
└─ scripts/            品牌产物与截图脚本

文档

文档 内容
docs/00-overview.md 定位、核心判断(推演 ≠ 仿真)、非目标、术语
docs/01-requirements.md 全量需求与逐条验收标准、NFR、已知不做
docs/02-domain-model.md 领域模型、数据 Schema、不变量
docs/03-catalog.md 设备/端口/线缆目录与五条物理硬约束
docs/04-architecture.md 分层、包边界、渲染方案、状态管理
docs/05-engine.md 链路协商、广播域、路由、逐跳推演、带宽、DNS、环路
docs/06-addressing.md IP / 网段 / VLAN / DHCP / DNS 模型
docs/07-diagnostics.md 诊断输出契约、原因码表、证据链呈现规范
docs/08-roadmap.md 里程碑、逐轮实测数据、已知缺口
docs/09-deployment.md 静态托管与基路径、Pages、容器镜像、端口、镜像仓库
docs/DECISIONS.md 决策记录(含「为什么没选另一条路」与代价)
CONTRIBUTING.md 环境、命令、代码约定、提交与文档习惯

质量

  • 单测在仓库里:引擎 45 项(Node,无 jsdom)、前端 221 项(几何 / 端口布局 / 侧栏布局 / 命令菜单 / store 行为 / 七套预置场景的行为承诺);pnpm check 一次跑完;
  • 端到端与规模压测用真实 Chromium 驱动,覆盖画布交互、四类诊断、侧栏排版与性能预算, 实测数据记在 docs/08-roadmap.md(810 台设备场景:拖动中位帧 33 ms);
  • 已知缺口(节点树无虚拟滚动、拖动态每帧重建世界等)同样记在路线图的"已知不足"里 —— 不藏在代码注释里。

参与开发

欢迎 issue 与 PR。请先读 CONTRIBUTING.md:环境与命令、代码约定、 以及这个仓库"新能力要带需求条目 + 决策记录 + 单测"的惯例。

第三方资源与许可

资源 许可 用途
Lucide ISC(商用免费,无需 UI 署名) 设备/端口/界面图标;画布 Path2D 与 SVG 组件共用同一份数据

项目不包含任何厂商设备镜像、商标素材或私有配置文件;目录中的设备与线缆参数均为公开标准 (TIA/EIA、IEEE 802.3/802.11、ISO/IEC 11801)的数值事实。

许可

MIT © 2026 Dynesshely

About

A browser-based network topology simulator, emulator, and analyzer for designing, testing, and visualizing network scenarios.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages