开始建设时,我们先追一件小事:一段文字怎样从甲的输入框,变成乙能够看见的来信?
先别要求绝对可靠。把这一条路径说清楚,才能知道下一步应该补在哪里。
在实验入口建立 V0 房间,先用无故障练习通道。甲输入一句可辨认的话,乙从自己的窗口接收,再用文字回复。
浏览器确实在和本机服务进行 HTTP 通信;两个角色端点与信道在服务内模拟。界面将这两个层次分开:发送请求成功只代表模拟器本地入队,不直接表示乙的角色收件箱已经取得消息,更不表示乙本人已经理解。
观察甲的本地发件、乙的来信和甲后来收到的回复。不要通过甲窗口寻找一个来自后台全局状态的“已送达”灯——它没有这样的旁路。
甲输入文字
→ 本机编码并接受入队
→ 模拟通道选择延迟、丢失或转交
→ 乙的角色端点接收并呈现
→ 乙决定怎样回复
→ 回复走同一类通道
→ 甲获得新证据
无故障练习便于先看到链路;下一轮换成不可靠通道,原信和回信都可能丢失。实际收到回信是一件事,没有收到回信能说明什么,则是另一件事。
甲自己的“发送成功”只覆盖本机这一步。乙说“我看见了”,是对其收件或阅读的声明。若乙说“我同意”,确认的语义又更强,但仍不是实际行动已经完成。
甲连续发送两次相同文字。乙只回复一次“收到了”。甲能自动知道,这次回复对应哪一封、哪一次发送吗?
如果双方事先约定每次只允许一封在途消息,也可能靠这个约定关联;也可以引用原文。但消息一多、内容重复或回复延迟,这些办法会出现成本与歧义。
界面显示的 A-out-1、B-in-1 是各自的本地记录序号。V0 没有把它们作为共同应用编号传给对方,不能因为调试台能把事件串起来,就假装角色也有同一份编号。
两人先同意这版信封的职责,再分工建设:
| 字段 | 这版负责表达什么 |
|---|---|
| protocol | 使用哪版消息约定 |
| id | 指出正在讨论哪一条应用消息 |
| from / to | 在固定两角色模型中声明发件方与收件方 |
| kind | 普通内容 data,或阶段回执 ack |
| body | data 的内容 |
| reply_to / stage | ack 对应谁,以及确认收到还是接受 |
本版 from/to 受到实验角色入口约束,这只是本地底座给出的前提。现实中的身份来源、密钥分发和安全传输还需要后续建设,不能只相信一个自报姓名的字段。
一位学习者沿 发送端建设线,负责把消息变成有边界的字节;另一位沿 接收端建设线,负责从任意分块中还原消息,并解释回执。
可以与 AI 共同设计或实现自己的部分。运行角色实验时,给 AI 的仍只能是本角色信息;建设时共同阅读协议不等于知道这一轮消息是否送达。
两条线最后在 互操作验收 汇合。读者应带回一段能运行的规则及其边界,而不是只把字段表背下来。