ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

无需轮询的双向通信:http_study完整实战WebSocket服务端与客户端

无需轮询的双向通信:http_study完整实战WebSocket服务端与客户端 无需轮询的双向通信http_study完整实战WebSocket服务端与客户端【免费下载链接】http_studyfollow me to study http项目地址: https://gitcode.com/gh_mirrors/ht/http_study本文带你用http_studyfollow me to study http开源项目在 OpenResty Nginx 环境中从零实战WebSocket 服务端与客户端一个 Lua 服务端脚本、一个 Lua 客户端脚本、一个 Python 客户端脚本三步跑通无需轮询的双向通信。为什么需要 WebSocket告别轮询 传统的 HTTP 通信是请求-响应模式客户端问一句服务器答一句。想要服务器主动推送消息只能靠轮询客户端每隔几秒问一次有新消息吗既浪费带宽又延迟高。WebSocketRFC 6455解决的就是这个问题客户端与服务器通过一次 HTTP 握手建立长连接连接建立后双方都可以主动推送数据无需反复发起请求典型场景即时聊天、股票行情、在线协作、游戏状态同步http_study项目正是围绕《透视 HTTP 协议》编写的学习仓库用 Nginx/OpenResty Lua 把每个知识点做成可运行的实验第 38 课就是 WebSocket 实战。环境准备一键克隆并启动如果本地还没有项目代码克隆仓库git clone https://gitcode.com/gh_mirrors/ht/http_study进入www/目录后只需执行启动脚本即可拉起整套 OpenResty 环境cd http_study/www ./run.sh start 也支持 Docker 方式docker pull chronolaw/http_study详见项目根目录的 docker-compose.yml 与 Dockerfile。启动后无需手工配置任何路由——www/conf/http/servers/locations.inc中有一个非常巧妙的正则 location# curl 127.1/07-1 location ~ ^/([\d|\-]) { default_type text/plain; content_by_lua_file lua/$1.lua; }见 locations.inc访问/38-0就会自动执行lua/38-0.lua访问/38-1执行lua/38-1.lua。这是 http_study 最省心的设计——每个实验一个脚本URL 即入口。第一步用 20 行 Lua 写一个 WebSocket 服务端 打开 38-0.lua整个服务端核心逻辑不到 50 行local server require resty.websocket.server local wb, err server:new{ timeout 5000, max_payload_len 1024 * 64, }OpenResty 自带的resty.websocket.server库帮我们屏蔽了握手帧的编解码细节server:new()就完成了一次 WebSocket 握手见 38-0.lua。之后就是一个while true循环不断收帧38-0.lua帧类型服务端行为说明pingwb:send_pong()心跳保活防止连接被中间设备掐断textwb:send_text(data..,..data)收到什么文本就回显拼接后的文本closewb:send_close()协商关闭连接超时继续等待区分 timeout 错误与真实错误避免误关连接这个小服务端的规则很简单你发monado我回monado,monado。麻雀虽小却完整覆盖了 WebSocket 的收发、心跳、关闭三大生命周期。第二步Lua 客户端与服务端对练 同一个 nginx worker 里还能直接用resty.websocket.client写客户端——见 38-1.lua流程一目了然local wb, err client:new{ timeout 5000, max_payload_len 1024 * 64, } local uri ws://127.0.0.1/38-0 local ok, err wb:connect(uri)连接wb:connect(uri)发起握手连接ws://127.0.0.1/38-0心跳send_ping()后收一帧pong打印recv pong业务send_text(hello websocket)收到回显hello websocket,hello websocket收尾send_close()正常断开见 38-1.lua在终端执行curl 127.0.0.1/38-1预期输出connect ok recv pong recv: hello websocket,hello websocket一行命令看到完整的连接→心跳→收发消息→关闭闭环这就是 WebSocket 双向通信的最小演示。第三步Python 客户端跨语言验证 更贴近真实场景的是用独立语言写客户端。python/websocket.py 只有 20 多行async with websockets.connect(uri) as ws: name monado await ws.send(name) print(f {name}) greeting await ws.recv() print(f {greeting})它连接同一个地址ws://127.0.0.1/38-0发送monado并打印服务端的回显。安装依赖后运行pip install websockets python python/websocket.py输出 monado monado,monado一个 Lua 服务端 一个 Lua 客户端 一个 Python 客户端三种视角验证同一条 WebSocket 连接非常适合理解协议是双方共同遵守的约定这一本质。抓包验证看清 WebSocket 握手过程 想亲眼看看 WebSocket 的 HTTP 升级握手吗项目贴心地附好了现成的抓包文件 38-1.pcapng。用 Wireshark 打开用过滤条件http.request.method GET websocket即可定位握手请求。握手阶段你会看到经典的三个头Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: 客户端随机值服务器返回101 Switching Protocols后TCP 连接从HTTP 语义切换为WebSocket 帧语义此后所有数据都以二进制帧传输——这就是一次握手、双向推送的底层原理。配置细节两个值得学习的小技巧 ⚙️超时与缓冲区resty.conf 中统一配置了lua_socket_read_timeout等 cosocket 超时与缓冲参数避免长连接因超时设置不当而异常断开。拒绝普通 HTTP 访问38-0.lua 里当握手失败即直接用 HTTP 访问/38-0时返回444状态码直接断连防止 WebSocket 端口被普通 HTTP 流量打杂。小结一条连接双向世界 本文用 http_study 的 3 个脚本完成了 WebSocket 的完整实战角色文件关键 APIWebSocket 服务端www/lua/38-0.luaresty.websocket.server/recv_frameLua 客户端www/lua/38-1.luaresty.websocket.client/send_textPython 客户端python/websocket.pywebsockets.connect/ws.recv抓包验证wireshark/38-1.pcapngRFC 6455 升级握手相比轮询WebSocket 用一次握手换来了一条全双工通道消息实时、开销更低、代码更直观。跑通这三个脚本后你就已经掌握了 WebSocket 服务端与客户端开发的核心骨架接下来只需把它接入聊天室、行情推送等真实业务即可。【免费下载链接】http_studyfollow me to study http项目地址: https://gitcode.com/gh_mirrors/ht/http_study创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表