1. 写在前面做后端开发的朋友应该都有过这样的经历页面上的数据要实时刷新轮询太浪费资源长连接又不好维护。后来接触了 WebSocket才发现这东西确实好用。今天不聊太深的理论就从一个实际的小需求出发用 Python、Java、PHP 三种语言分别写一个最简单的推送 Demo把消息从服务端推到客户端。代码都不长跑起来就能看到效果。2. WebSocket 到底解决了什么问题以前我们做消息推送最常用的办法就是前端定时去问后端“有没有新消息”也就是轮询。这种方式实现简单但服务器压力大而且消息不及时。WebSocket 不一样它是一条全双工的通道服务端可以主动把消息推给客户端不用等客户端来问。像在线聊天、订单提醒、后台通知这类场景用 WebSocket 就非常合适。简单理解WebSocket 就是让浏览器和服务器之间建立一条“常驻”的管道两边随时都能往管道里塞数据。下面我们就用三种语言分别搭一条这样的管道。3. Python 版用 websockets 库实现Python 这边我习惯用websockets这个库安装和写起来都比较顺手。先装依赖pip install websockets然后写一个最简单的服务端监听 8765 端口收到客户端连接后主动推一条消息过去import asyncio import websockets async def handler(websocket, path): # 客户端连上来之后主动推送一条消息 await websocket.send(Hello from Python WebSocket!) print(消息已推送) async def main(): async with websockets.serve(handler, localhost, 8765): print(服务已启动端口 8765) await asyncio.Future() # 保持运行 if __name__ __main__: asyncio.run(main())客户端这边用浏览器或者写个小脚本都行。用 Python 客户端验证一下import asyncio import websockets async def client(): async with websockets.connect(ws://localhost:8765) as ws: msg await ws.recv() print(收到消息:, msg) asyncio.run(client())跑起来之后服务端控制台会打印“消息已推送”客户端会打印收到的内容。整个流程非常直观。4. Java 版用 Spring Boot WebSocketJava 这边我用 Spring Boot 来做因为它在 WebSocket 这块封装得比较成熟配置也少。先建一个 Spring Boot 项目引入依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-websocket/artifactId /dependency然后写一个 WebSocket 配置类把处理器注册进去import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; Configuration EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new PushHandler(), /push).setAllowedOrigins(*); } }再写一个处理器类客户端连上来之后服务端主动推送一条消息import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; public class PushHandler extends TextWebSocketHandler { Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 连接建立后主动推送 session.sendMessage(new TextMessage(Hello from Java WebSocket!)); System.out.println(消息已推送); } }启动项目后浏览器里打开一个 WebSocket 测试页面连接ws://localhost:8080/push就能收到服务端推过来的消息。这里要注意Spring Boot 默认端口是 8080如果改了端口记得同步调整连接地址。5. PHP 版用 Workerman 实现PHP 做 WebSocket 一般会借助 Workerman 这个常驻内存框架它本身对长连接支持得比较好。先通过 Composer 安装composer require workerman/workerman然后写一个简单的服务端脚本监听 2346 端口客户端连上来后推送一条消息?php use Workerman\Worker; require_once __DIR__ . /vendor/autoload.php; $worker new Worker(websocket://0.0.0.0:2346); $worker-onConnect function ($connection) { // 客户端连上来之后主动推送 $connection-send(Hello from PHP WebSocket!); echo 消息已推送\n; }; Worker::runAll();启动方式也简单在命令行里执行php server.php start客户端连接ws://localhost:2346就能收到消息。Workerman 的好处是它本身是常驻进程不用依赖 PHP-FPM适合做实时推送这类场景。6. 三种实现放一起对比语言核心依赖启动方式适用场景Pythonwebsockets直接运行脚本轻量工具、快速原型JavaSpring Boot启动 Spring 应用企业级项目、复杂业务PHPWorkerman命令行常驻进程中小型实时应用选哪种语言主要看你的项目技术栈和团队熟悉程度。如果只是做个内部小工具Python 最省事如果是正式业务系统Java 的生态更完整PHP 项目里想加实时推送Workerman 是个不错的选择。7. 踩坑提醒最后说几个我实际踩过的坑给大家提个醒。第一WebSocket 连接是长连接服务端要注意心跳检测不然客户端断网了服务端还不知道。第二跨域问题浏览器里调试的时候记得把跨域放开不然连接会被拦下来。第三生产环境一定要上 SSL也就是 wss 协议不然浏览器会拒绝连接。这几个 Demo 虽然简单但把核心链路跑通了。后面要做的无非是加上消息广播、用户鉴权、消息持久化这些思路都是一样的。希望这篇文章能帮刚接触 WebSocket 的朋友少走点弯路。