# netty-websocket **Repository Path**: waynedu/netty-websocket ## Basic Information - **Project Name**: netty-websocket - **Description**: No description available - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-31 - **Last Updated**: 2026-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Netty WebSocket Demo 基于 Spring Boot 3 + Netty 实现的 WebSocket 客户端/服务端 Demo 项目。 ## 📋 项目简介 本项目演示了如何使用 Netty 构建高性能的 WebSocket 服务端和客户端,支持: - 双向消息通信 - 客户端管理 - 消息广播 - 自动重连机制 ## 🛠️ 技术栈 | 技术 | 版本 | 说明 | |------|------|------| | Java | 17 | 编程语言 | | Spring Boot | 3.2.0 | 应用框架 | | Netty | 4.1.100.Final | 高性能网络框架 | | Lombok | 1.18.30 | 简化代码 | | Jackson | 2.15.3 | JSON处理 | ## 📁 项目结构 ``` netty-websocket/ ├── pom.xml # 父项目配置 ├── README.md # 项目文档 ├── netty-websocket-common/ # 公共模块 │ ├── pom.xml │ └── src/main/java/com/example/nettywebsocket/common/ │ ├── model/ # 数据模型 │ │ ├── Message.java # 消息模型 │ │ └── ClientInfo.java # 客户端信息 │ └── util/ # 工具类 │ ├── MessageSerializer.java # JSON序列化 │ └── IdGenerator.java # ID生成器 ├── netty-websocket-server/ # 服务端模块 │ ├── pom.xml │ └── src/main/ │ ├── java/com/example/nettywebsocket/server/ │ │ ├── NettyWebSocketServerApplication.java # 启动类 │ │ ├── boot/ # 启动相关 │ │ │ ├── NettyWebSocketServer.java │ │ │ └── ServerStartupRunner.java │ │ ├── config/ # 配置类 │ │ │ ├── WebSocketServerConfig.java │ │ │ └── NettyServerProperties.java │ │ ├── controller/ # REST控制器 │ │ │ └── WebSocketController.java │ │ ├── handler/ # Netty处理器 │ │ │ ├── WebSocketServerHandler.java │ │ │ └── WebSocketServerInitializer.java │ │ └── service/ # 业务服务 │ │ ├── ClientService.java │ │ └── impl/ClientServiceImpl.java │ └── resources/ │ ├── application.yml # 应用配置 │ └── logback-spring.xml # 日志配置 └── netty-websocket-client/ # 客户端模块 ├── pom.xml └── src/main/ ├── java/com/example/nettywebsocket/client/ │ ├── NettyWebSocketClientApplication.java # 启动类 │ ├── boot/ # 启动相关 │ │ ├── NettyWebSocketClient.java │ │ └── ClientStartupRunner.java │ ├── config/ # 配置类 │ │ ├── WebSocketClientConfig.java │ │ └── NettyClientProperties.java │ ├── controller/ # REST控制器 │ │ └── WebSocketClientController.java │ ├── handler/ # Netty处理器 │ │ ├── WebSocketClientHandler.java │ │ └── WebSocketClientInitializer.java │ └── listener/ # 事件监听 │ ├── MessageListener.java │ └── DefaultMessageListener.java └── resources/ ├── application.yml # 应用配置 └── logback-spring.xml # 日志配置 ``` ## 🚀 快速开始 ### 环境要求 - JDK 17+ - Maven 3.8+ ### 编译项目 ```bash cd netty-websocket mvn clean install -DskipTests ``` ### 启动服务端 ```bash java -jar netty-websocket-server/target/netty-websocket-server-1.0.0.jar ``` 服务端启动后: - REST API: http://localhost:8080 - WebSocket: ws://localhost:8081/ws ### 启动客户端 ```bash java -jar netty-websocket-client/target/netty-websocket-client-1.0.0.jar ``` 客户端启动后: - REST API: http://localhost:8082 - 自动连接到 WebSocket 服务端 ### 使用前端页面调试 ```bash # 启动HTTP服务器提供前端页面 cd netty-websocket python3 -m http.server 8083 ``` 然后访问:http://localhost:8083/index.html ## 🔌 API 接口 ### 服务端接口 | 方法 | 路径 | 描述 | |------|------|------| | GET | /api/websocket/clients | 获取所有在线客户端 | | GET | /api/websocket/clients/count | 获取在线客户端数量 | | GET | /api/websocket/clients/{clientId} | 获取指定客户端信息 | | POST | /api/websocket/clients/{clientId}/message | 发送消息给指定客户端 | | POST | /api/websocket/broadcast | 广播消息给所有客户端 | #### 获取在线客户端列表 ```bash curl http://localhost:8080/api/websocket/clients ``` #### 广播消息 ```bash curl -X POST http://localhost:8080/api/websocket/broadcast \ -H "Content-Type: application/json" \ -d '{"content": "Hello World!"}' ``` ### 客户端接口 | 方法 | 路径 | 描述 | |------|------|------| | POST | /api/client/connect | 连接到服务器 | | POST | /api/client/disconnect | 断开连接 | | GET | /api/client/status | 获取连接状态 | | POST | /api/client/send | 发送消息到服务器 | | POST | /api/client/broadcast | 通过服务器广播消息 | #### 发送消息 ```bash curl -X POST http://localhost:8082/api/client/send \ -H "Content-Type: application/json" \ -d '{"content": "Hello from Client!"}' ``` ## 📊 消息格式 ### Message 模型 ```json { "messageId": "string", // 消息唯一ID "senderId": "string", // 发送者ID "receiverId": "string", // 接收者ID(为空则广播) "type": "TEXT", // 消息类型:TEXT, JSON, BINARY, PING, PONG, CONNECT, DISCONNECT "content": "string", // 消息内容 "timestamp": "2024-01-01T12:00:00" // 发送时间 } ``` ### ClientInfo 模型 ```json { "clientId": "string", // 客户端唯一标识 "ipAddress": "string", // 客户端IP地址 "connectTime": "2024-01-01T12:00:00", // 连接时间 "lastActiveTime": "2024-01-01T12:00:00", // 最后活跃时间 "status": "CONNECTED" // 状态:CONNECTED, DISCONNECTED, IDLE } ``` ## ⚙️ 配置说明 ### 服务端配置 文件:`netty-websocket-server/src/main/resources/application.yml` ```yaml server: port: 8080 # Spring Boot REST端口 websocket: server: port: 8081 # WebSocket端口 path: /ws # WebSocket路径 boss-threads: 1 # Boss线程数(接受连接) worker-threads: 4 # Worker线程数(处理业务) netty: server: connect-timeout: 30000 # 连接超时(ms) receive-buffer-size: 65536 # 接收缓冲区大小 send-buffer-size: 65536 # 发送缓冲区大小 tcp-no-delay: true # 禁用Nagle算法 keep-alive: true # 保持连接 backlog: 1024 # 最大等待连接数 ``` ### 客户端配置 文件:`netty-websocket-client/src/main/resources/application.yml` ```yaml server: port: 8082 # Spring Boot REST端口 websocket: client: host: localhost # 服务器地址 port: 8081 # 服务器端口 path: /ws # WebSocket路径 connect-timeout: 10000 # 连接超时(ms) reconnect-interval: 5000 # 重连间隔(ms) max-reconnect-attempts: 5 # 最大重连次数 auto-reconnect: true # 是否自动重连 netty: client: receive-buffer-size: 65536 # 接收缓冲区大小 send-buffer-size: 65536 # 发送缓冲区大小 tcp-no-delay: true # 禁用Nagle算法 keep-alive: true # 保持连接 ``` ## 🔄 工作流程 ### 服务端启动流程 1. `NettyWebSocketServerApplication` 启动 2. Spring 容器初始化 3. `NettyWebSocketServer` 通过 `@PostConstruct` 启动 Netty 服务器 4. 绑定端口 8081,等待客户端连接 5. 客户端连接时,`WebSocketServerHandler` 处理握手和消息 ### 客户端启动流程 1. `NettyWebSocketClientApplication` 启动 2. Spring 容器初始化 3. `ClientStartupRunner` 在启动后自动连接服务器 4. `NettyWebSocketClient` 建立 WebSocket 连接 5. `WebSocketClientHandler` 处理消息接收 ### 消息传递流程 ``` 客户端发送消息 ↓ WebSocketClientHandler.channelRead0() ↓ Netty发送到服务端 ↓ WebSocketServerHandler.channelRead0() ↓ ClientService.broadcastMessage() ↓ 发送到所有客户端 ↓ 客户端WebSocketClientHandler接收 ↓ MessageListener.onMessageReceived() ``` ## 🧩 核心组件说明 ### 服务端核心组件 | 组件 | 职责 | |------|------| | `NettyWebSocketServer` | Netty服务器启动和生命周期管理 | | `WebSocketServerInitializer` | Channel Pipeline配置 | | `WebSocketServerHandler` | 消息处理和连接管理 | | `ClientService` | 客户端管理服务接口 | | `ClientServiceImpl` | 客户端管理实现(并发安全) | | `WebSocketController` | REST API控制器 | ### 客户端核心组件 | 组件 | 职责 | |------|------| | `NettyWebSocketClient` | Netty客户端连接和消息发送 | | `WebSocketClientInitializer` | Channel Pipeline配置 | | `WebSocketClientHandler` | 消息接收和握手处理 | | `MessageListener` | 消息事件监听接口 | | `DefaultMessageListener` | 默认消息监听器 | | `WebSocketClientController` | REST API控制器 | ## 📝 代码示例 ### 发送消息(服务端) ```java // 创建消息 Message message = Message.builder() .messageId(IdGenerator.generateMessageId()) .senderId("SERVER") .receiverId(clientId) // 为空则广播 .type(Message.MessageType.TEXT) .content("Hello!") .timestamp(LocalDateTime.now()) .build(); // 发送给指定客户端 clientService.sendMessageToClient(clientId, message); // 广播给所有客户端 clientService.broadcastMessage(message); ``` ### 发送消息(客户端) ```java // 创建消息 Message message = Message.builder() .messageId(IdGenerator.generateMessageId()) .senderId("CLIENT") .type(Message.MessageType.TEXT) .content("Hello from Client!") .timestamp(LocalDateTime.now()) .build(); // 发送到服务器 webSocketClient.sendMessage(message); ``` ## 🧪 测试验证 ### 测试步骤 1. **启动服务端** ```bash java -jar netty-websocket-server/target/netty-websocket-server-1.0.0.jar ``` 2. **启动客户端** ```bash java -jar netty-websocket-client/target/netty-websocket-client-1.0.0.jar ``` 3. **验证连接** ```bash curl http://localhost:8080/api/websocket/clients/count # 输出: {"count":1} ``` 4. **服务端发送消息** ```bash curl -X POST http://localhost:8080/api/websocket/broadcast \ -H "Content-Type: application/json" \ -d '{"content":"Hello from Server!"}' ``` 5. **客户端发送消息** ```bash curl -X POST http://localhost:8082/api/client/send \ -H "Content-Type: application/json" \ -d '{"content":"Hello from Client!"}' ``` ### 预期结果 - 服务端日志显示客户端连接和消息接收 - 客户端日志显示收到服务端消息 - 消息在客户端之间正确广播 ## 🔧 常见问题 ### Q1: 端口被占用 **问题**: 启动时提示端口被占用 **解决方案**: ```bash # 查找占用端口的进程 lsof -ti:8080 | xargs kill -9 lsof -ti:8081 | xargs kill -9 lsof -ti:8082 | xargs kill -9 ``` ### Q2: 客户端无法连接 **检查项**: 1. 服务端是否已启动 2. 服务端端口是否正确(默认8081) 3. 防火墙是否允许连接 4. 网络是否可达 ### Q3: 消息发送失败 **检查项**: 1. 客户端是否已连接(`GET /api/client/status`) 2. 消息格式是否正确(JSON格式) 3. 服务端日志是否有错误信息 ## 📚 参考资料 - [Netty官方文档](https://netty.io/wiki/) - [WebSocket协议规范](https://datatracker.ietf.org/doc/html/rfc6455) - [Spring Boot官方文档](https://docs.spring.io/spring-boot/docs/current/reference/html/) ## 📄 许可证 MIT License --- *项目已通过编译和测试验证,可直接运行使用。*