如何在公网服务器而非本地主机上使用Tornado实现WebSocket?
如何将连接外部设备的本地WebSocket服务暴露给公网访问
看起来你已经搞定了本地WebSocket的运行,核心问题是你的WebSocket服务器必须留在连接外部设备的机器上,没法直接部署到公网服务器,所以我们需要把这台机器上的WebSocket服务暴露给公网,让任意设备都能连接。下面分步骤帮你解决:
1. 先修改WebSocket服务的监听地址
你的websocket.py当前默认只监听localhost,这会导致只有本机能访问。我们需要让它监听机器上所有可用的网络接口:
找到这一行:
application.listen(8001)
修改为:
application.listen(8001, address='0.0.0.0')
0.0.0.0表示监听所有网卡的请求,不管是本机、局域网还是公网来的连接,这样外部设备才能找到你的WebSocket服务。
2. 让公网能访问到你的WebSocket服务
这里分两种情况,根据你的网络环境选择:
情况A:连接外部设备的机器有公网IP
如果你的机器直接有公网IP(比如云服务器、或者家里宽带分配了固定公网IP):
- 先确认公网IP:在这台机器上通过命令行
curl icanhazip.com查看,或者访问IP查询工具获取。 - 配置防火墙:打开机器的防火墙(Windows Defender防火墙/Linux iptables),允许入站端口8001的TCP连接;如果是家用路由器,还要在路由器后台设置端口转发,把外部的8001端口转发到这台机器的局域网IP和8001端口。
- 修改前端连接地址:把
index.html里的WebSocket连接代码改成:var connection = new WebSocket('ws://你的公网IP:8001/websocket');
情况B:连接外部设备的机器没有公网IP(大部分家用网络)
这种情况需要用内网穿透工具,把本地的8001端口映射到公网域名,推荐用ngrok(新手友好):
- 去ngrok官网下载对应系统的安装包并解压到本地机器。
- 在命令行运行:
ngrok http 8001 - 运行后你会看到类似这样的输出:
Forwarding http://abc123.ngrok.io -> http://localhost:8001 Forwarding https://abc123.ngrok.io -> http://localhost:8001 - 修改前端连接地址:用ngrok提供的域名,把WebSocket连接改成:
(注意用var connection = new WebSocket('wss://abc123.ngrok.io/websocket');wss,ngrok默认支持加密连接,避免浏览器的安全限制)
⚠️ 注意:ngrok免费版的域名每次重启都会变,如果需要长期稳定使用,可以考虑付费版,或者自己搭建FRP这类内网穿透服务。
3. 测试验证
- 先在局域网内其他设备测试:用这台机器的局域网IP+8001(比如
ws://192.168.1.100:8001/websocket),能正常接收数据说明本地服务配置没问题。 - 公网测试:用手机流量(不要连同一个WiFi)访问你的网页,看是否能实时接收数据。
常见问题排查
- 连接失败:检查防火墙是否开放8001端口、路由器端口转发是否正确、ngrok是否正常运行。
- 浏览器报错“不安全的WebSocket连接”:用
wss协议(比如ngrok的https域名对应wss),或者给你的公网IP配置SSL证书(比如用Let's Encrypt)。 - 数据不更新:确认WebSocket服务在连外部设备的机器上正常运行,且外部设备的数据能正常传入WebSocket脚本。
内容的提问来源于stack exchange,提问作者Paran0id_Andr0id




