接着上一篇说。上一篇讲的是"怎么发话",这一篇讲更前面的一步:怎么让两台电脑说上话。
我手头是两台不同网络的机器——一台在家里,一台跟着我走。让它们上面的 AI 互相派活,第一步不是写指令,是解决"它们压根够不着对方"。
我前后试了三条路,只有第三条通了。
先问一句,能省半天
动手之前最该问的一句话是:
那两台机器,是不是同一个 WiFi/同一个路由器下的?
这句话决定后面所有事:
- 同一个网 → 局域网直连,最简单,几乎不用配置;
- 不同网 → 只能走隧道那一类方案。
但这里有个反直觉的地方,我一开始就踩了:用扫描工具扫不到对方机器上的 AI 服务,不代表它们不在同一个网。
因为装在机器里的服务默认只听自己家的回声(只听本机地址),外面的人怎么扫都扫不到。判断同不同网,得看三个东西:两台机器互相能 ping 通、它们在路由器下拿到的地址属于同一个网段、对方已经把那个服务的大门开出来。
扫描工具扫不到,只能说明"服务没对外开放",不能说明"不在同一个网"。
路一:同一个网里直连——最快,但只解决一半
如果两台机器在同一个路由器下,事情很简单:把服务的大门开出来,对方直接用内网地址访问就行。
代价是这套方案只在"同一个网"成立。我那两台机器不是——一台在家,一台在外地。所以这条路对我只解决了一半问题。
路二:现成的异地组网工具——在国内没连上
第二类思路是"用别人做好的异地组网工具":两台机器都装上它的客户端、登录同一个账号,它就给你俩各分配一个虚拟地址,像在同一个网里一样。
这个思路本身没问题,问题在环境:九月初我实测过,它的中心服务器在国内根本连不上,一直超时。
它不是不好用,是这类工具都得先登录它自己的中心服务器去领地址——第一步就出不去,后面免谈。
选型这件事我的教训是:能不用"要先连上别人家服务器"的方案,就别用。先在自己这台机器上测能不能连上,再谈功能。
路三:自己架一条隧道——唯一通的一条
第三条路是我最后用的,也是唯一跑通的。原理用一句话讲:
两台机器都藏在路由器后面,谁也没有门牌号,互相找不到。办法是让两台机器各自主动往外打个电话出去,让外面的大平台记住这条线;以后互发消息,报平台给的号,它顺着手里这条线把消息送回来。
细节上是这样:
- 家里的路由器给每台电脑的都是内部房号(形如 192.168.x.x),出了门没人认;运营商也不给固定门牌。
- 硬要做只能在自己路由器上开端口映射——但家宽的地址大多是运营商的大内网,根本映射不出去;就算能开,等于把自家大门敞在互联网上,几天就会被扫号机器盯上。
- 而"主动往外打电话"是路由器必须放行的动作——因为那跟你打开浏览器上网走的是同一个门。这条线拨出去之后不挂断,平台就给它挂一个网址;别人访问这个网址时,平台顺着那条已经通的线,把流量倒回你电脑上的收件箱。
打个比方:公司总机。你不用去申请一条专线(公网门牌),自己先拨给总机(主动向外),总机给你一个分机号(网址);外人拨分机号,总机接进你。因为这条线是你自己先拨出去的,防火墙当它是正常上网,不拦。
我选它还有个顺手的理由:我的域名和内容站已经跑在同一家平台上了,这条路等于复用现成的通道,不用新注册任何东西。
坑一:新版本把老参数删了
第一条坑比较常规:那个隧道工具的新版本把某个命令行参数删掉了,照着老资料写命令,直接报:
Incorrect Usage. flag provided but not defined: -api-token
改成走接口建隧道就通了。看到"参数不存在"这种报错,先怀疑版本,别反复改写法。
坑二:脚本发的请求,被当成机器人拦在门口
这个坑最费时间,也最值得写下来。
现象是:发出去的请求被拒,错误码 1010;可就在同一时刻,我手动敲命令访问同一个地址,一切正常。
原因:那家平台有一道"浏览器完整性检查",它按请求方自报的身份来判断是不是机器人。脚本发出的请求,默认那个身份一眼就是程序,于是被拦。手动命令的那次恰好没触发。
修法很朴素:给请求带一个正常的身份标识,立刻变 200。
这个坑为什么最坑:它的表现是"发了没反应"。 看起来特别像"对方那台机器没配好",我当时差一点就去重装对面那台机器了。
所以这条我写进了排障第一条:
"发了没反应"这五个字,先查自己这一侧的门口,再怀疑对面。
坑三:密钥在"显示层"被打码,对方以为文件不全
第三个坑更玄。
我给另一台机器写了份配置指南,里面有一串运行密钥。对面读完回报:"指南里密钥是省略形式,eyJhIj...0ifQ==,我全盘找过了(桌面、文档、下载、家目录),没有完整值,不是我漏了。"
但文件里那串是完整的。
真相是:密钥一旦被"打印/回显"出来,就会在显示层自动打码——而且它可能还保留着原来的长度,看起来特别像真的。肉眼、搜索、打印,全都看不出来。
解法是绕开内容、用哈希:
| 谁 | 做什么 |
|---|---|
| 源方 | 报出「长度 + 哈希值前 16 位」,例如 240 位、1dc88630b7994a12 |
| 接收方 | 自己从文件里提取并计算一遍,对比 |
对不上,才是真的没取到。而且校验码不是密钥本身,可以安全地在聊天里传。
我因此定了一条看起来别扭、但很必要的规矩:
"密钥缺失"这个结论,必须由哈希闭环证明,不能靠回显的内容推断。
一张排障速查表
跑起来之后我整理了一张表,现在基本照着它查:
| 看到什么 | 真实含义 | 怎么办 |
|---|---|---|
530 + error code: 1033 |
隧道在,但没有连接器在线(进程没跑) | 去看对面进程在不在 |
| 502 | 连接器在线,但本地服务没响应(端口不对/服务没开) | 查本机健康检查地址 |
200 + {"status":"ok"} |
隧道 + 服务都通 | 可以派活了 |
202 {"status":"accepted"} |
签名通过、已受理 | 202 就是成功,别只认 200 |
401 Invalid signature |
验签失败 | 两端密钥不一致,或时钟差太多 |
403 error code: 1010 |
被平台的机器人检查拦了 | 给请求带正常身份标识 |
还有一条经验:在 502 和 530 之间来回跳,不是配置错,是连接器在反复掉线(进程没常驻)。这时候别去改配置,去让进程常驻。
小结
三条路走下来,我的结论就三句:
- 先问"是不是同一个网",这一句能省半天;
- 家庭网络下,能通的永远是"主动往外拨一条长连接"这一类,不是"等外面连进来"那一类;
- 两个最坑的故障都伪装成同一句话——"对方没反应"。一个是门口被拦,一个是内容在显示层被打码。
线通了,才轮到上一篇讲的"怎么发话"。下一篇说一个更细的活:同一件小事,我为什么要分三封指令才办完——以及那次暴露出的、我自己的毛病。