客户端无法连接Socket:网页JS连接树莓派Socket失败求助
问题分析与解决方案
嘿,我来帮你搞定这个问题!核心原因其实很简单:你用Python写的是普通TCP Socket服务器,但网页里尝试用WebSocket协议去连接,这俩完全不是一个东西,自然会出问题。
为什么会失败?
WebSocket不是普通的TCP连接,它有自己的握手规则——浏览器发起连接时会先发送一个HTTP格式的握手请求,要求升级到WebSocket协议。你的普通Python Socket根本看不懂这个请求,处理不了就直接崩溃,浏览器那边就会提示“无法建立连接”,服务器端也会出现“管道破裂”的错误。
怎么解决?
我们需要把Python的普通Socket改成WebSocket服务器,这里推荐用轻量易用的websockets库,步骤如下:
1. 安装WebSocket库
在树莓派的终端里运行:
pip3 install websockets
2. 改写Python服务器代码
把原来的普通Socket脚本换成下面的WebSocket服务器代码(比如保存为ws_server.py):
import asyncio import websockets import random async def handle_client(websocket): # 持续给客户端发送随机数 while True: rand_num = random.randint(1, 100) # 生成1-100的随机数 await websocket.send(str(rand_num)) # 发送给客户端 await asyncio.sleep(1) # 每秒发一次 async def main(): # 启动WebSocket服务器,监听所有网卡的8080端口 async with websockets.serve(handle_client, "0.0.0.0", 8080): await asyncio.Future() # 保持服务器一直运行 if __name__ == "__main__": asyncio.run(main())
3. 修改网页端的JS代码
之前的URL里加了/ws路径,但我们的服务器没有设置这个子路由,直接去掉就行。另外要在onmessage回调里把收到的随机数打印到控制台:
<!DOCTYPE html> <html> <head> <title>WebSocket随机数测试</title> </head> <body> <script> // 建立WebSocket连接 const ws = new WebSocket('ws://192.168.137.2:8080'); // 连接成功时的提示 ws.onopen = () => { console.log('✅ WebSocket连接成功!'); }; // 收到服务器发来的随机数时,打印到控制台 ws.onmessage = (event) => { const randomNum = event.data; console.log('📥 收到随机数:', randomNum); // 如果想在页面上显示,也可以加一行: // document.body.insertAdjacentHTML('beforeend', `<p>当前随机数:${randomNum}</p>`); }; // 连接关闭时的提示 ws.onclose = () => { console.log('❌ WebSocket连接已关闭'); }; // 错误处理 ws.onerror = (error) => { console.error('⚠️ WebSocket出错:', error); }; </script> </body> </html>
4. 运行测试
- 在树莓派上启动WebSocket服务器:
python3 ws_server.py
- 把上面的HTML文件放到树莓派的
/var/www/html目录下(比如命名为ws_test.html)。 - 在桌面的Firefox里访问
http://192.168.137.2/ws_test.html,按下F12打开控制台,就能看到每秒打印的随机数啦!
额外注意事项
- 确保树莓派的8080端口没有被其他程序占用(之前的普通Socket脚本要先关掉)。
- 不要直接在本地打开HTML文件(
file://协议),这样可能会有浏览器安全限制,一定要通过树莓派的Apache服务器访问。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

