一个可以在线多人玩的五子棋开发与布署方法-WebRTC和WebSocket的测试方法 总览这个横型是基于个后台websocket ,python ,和一个index.html网页。一开始AI给出的是Node.js的server.js文件。但是也轻易换成了python.他想用vue,和其他框架我说先不用了我测下通道。于是有了下午8小时的折腾。我说下基于ddnsto是实现放在互联网上的虽然他只支持http,内总https外部。这里我重点说下外总的https,透传是如何代理websocket r wss://协议的。这个很有看头。我最后会提供全部代码在资源中分步安装docker docker-compose安装filebrowser.容器建立源码目录和python 3.11容器开通static,和websocket服务安装NginxUI,和配置反代主要是websocket.到子目录核心坑安装docker时用了国内的几个镜像在debian下安装的镜像好像不行用某问原厂的安装过程居然速度很快也就是docker 可能活着。拉镜像必须用几个国内的源因为有的好几百M难用的很慢。前面说了filebrowser的密码要改短点不然真难用不安全用长度解决。不能用机制的吗比如把强试的路档死呢也许档不死吧。这个项目说要停止维护要找个第三方。它主要用来在线写和改文件。 目录的权力分配好像不太好把握。测试就无所谓生产要慎重。我定制了python启动代码。 让8000的http.server做保底。在启动后docker exec -it 用python server.py咆主程序。要在本地咆通需要在insex.html中的 WS_URL 定制成自已的IP。并在布署到ddnsto后改成域名的地址这是new WebSocket (WS_URL)的握手地址。nginx proxy manager 这个NPM 不是我的菜因为太大拉起来费劲NginxUI小很多是go 的。在安装时10分钟有效会在内决/etc/nginxUI/.installsecret. 这个是进入的第一次的凭证。一开始没上官网没有找到全程在AI聊天。 这个已经在开始yaml compse 中指向了外部data.ws到子目录的nginx反代这个是最后一个。 在新建站点时关注点在于把ws/这个location定义成‘ location /ws/{proxy_pass http://127.0.0.1:3000/;# 替换为你的后端服务地址# ✨ WebSocket 核心三件套必须添加proxy_http_version1.1;# 1. 必须使用 HTTP/1.1 版本proxy_set_header Upgrade$http_upgrade;# 2. 透传客户端的 Upgrade 头proxy_set_header Connectionupgrade;# 3. 明确指示协议升级# 传递真实客户端信息proxy_set_header Host$host;proxy_set_header X-Real-IP$remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;# ⏱️ 长连接超时控制极其重要proxy_read_timeout 3600s;# 默认60秒太短WebSocket长连接必须调大proxy_send_timeout 3600s;}“站点要先保存再启用基本上可以用在配置管里中要把原来80换走走为容器只转出了80,9000, 要是不想再启动一次需要让出80-到9000管理口的转发。说了这么多就能上云了上云时需要扫一下微信就会转到工作台了。在云上为了做测试在云上的速度需要在ddnsto开通一个二级域名到家中接口docker, nginx反代服务的转发。先去安装一下ddnsto。 控制台会有安装方法Docker , Nas, Openwrt. 这是主流的三种安种环境。完成的后的配置是一步到位的。但是有个巨大的能力短板 谁开通谁用。也就是这个二级域名好像是专门绑定微信的。 试用是免费7天用我的可以免3个月可以和我交流用起来的感受。https://web.kooldns.cn/app/#/login?affI4D8SPM1源码我上传到资源我一步到位全部上传吧这是8小时的工作成果。测了网速可以落子。体会一下server.py全打包资源不一对一讲解https://download.csdn.net/download/wjcroom/93388118importasyncioimportjsonimporttimeimportwebsockets# 存储当前所有在线的客户端和房间信息# 格式: {room_id: {player_id: websocket}}rooms{}async def handle_client(websocket):处理单个客户端的连接与消息 room_idNone player_idNone try: asyncformessageinwebsocket: try: datajson.loads(message)actiondata.get(action)# 1. 加入房间ifactionjoin:room_iddata.get(roomId)player_iddata.get(playerId)ifroom_id notinrooms: rooms[room_id]{}rooms[room_id][player_id]websocket# 通知房间内其他玩家有新成员加入await broadcast(room_id,{action:system,message:f玩家 {player_id} 加入了房间}, websocket)# 2. 游戏操作落子、悔棋等elifactionmove:ifroom_id and room_idinrooms:# 将落子数据转发给同房间的其他玩家await broadcast(room_id,{action:move,playerId:player_id,row:data.get(row),col:data.get(col),timestamp:data.get(timestamp)}, websocket)# 3. 性能测试Ping-Pongelifactionping:await websocket.send(json.dumps({action:pong,clientTime:data.get(clientTime),serverTime:int(time.time()*1000)}))except json.JSONDecodeError: await websocket.send(json.dumps({error:无效的 JSON 格式}))except websockets.exceptions.ConnectionClosed: print(f客户端断开连接: {player_id})finally:# 客户端断开时从房间中移除ifroom_id and player_id and room_idinrooms:ifplayer_idinrooms[room_id]: del rooms[room_id][player_id]await broadcast(room_id,{action:system,message:f玩家 {player_id} 离开了房间})# 如果房间空了清理房间ifnot rooms[room_id]: del rooms[room_id]async def broadcast(room_id, message,sender_socketNone):向房间内除发送者外的所有客户端广播消息ifroom_id notinrooms:returnmsg_strjson.dumps(message)tasks[]forpid, wsinrooms[room_id].items():ifws!sender_socket: tasks.append(ws.send(msg_str))iftasks: await asyncio.gather(*tasks,return_exceptionsTrue)async def main():启动 WebSocket 服务器 print( 五子棋信令服务器已启动监听端口 3000...)async with websockets.serve(handle_client,0.0.0.0,3000): await asyncio.Future()# 永久挂起保持服务器运行if__name____main__:asyncio.run(main())