下面是一個基於 Spring Boot + Netty + WebSocket 實現的消息通知系統的完整思路與核心代碼示例。整個架構旨在實現高併發下的實時推送,同時兼顧擴展性與可維護性 💡。
🚀 一、系統架構原理
系統由三層構成:
| 模塊 | 功能説明 | 技術核心 |
|---|---|---|
| Spring Boot | 提供 REST 接口與業務邏輯層 | 控制消息發送與用户管理 |
| Netty | 負責底層 TCP 長連接管理 | 高性能 I/O,多路複用 |
| WebSocket | 實現客户端與服務端實時通信 | 基於 HTTP 升級協議 |
核心邏輯:客户端建立 WebSocket 連接 → Netty 管理 Channel → 服務端通過 REST 接口向指定用户推送消息。
🧩 二、項目核心依賴
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.111.Final</version>
</dependency>
</dependencies>
説明:
spring-boot-starter-web:用於提供 HTTP 接口。netty-all:提供底層事件循環和 WebSocket 通道支持。
⚙️ 三、Netty WebSocket 服務端實現
@Component
public class WebSocketServer {
private final int port = 8088; // WebSocket監聽端口
public void start() throws InterruptedException {
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new WebSocketInitializer());
Channel ch = bootstrap.bind(port).sync().channel();
System.out.println("🚀 WebSocket服務啓動,端口:" + port);
ch.closeFuture().sync();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
解釋:
EventLoopGroup:管理事件循環線程。ServerBootstrap:啓動 Netty 服務器。WebSocketInitializer:自定義初始化器,負責管道配置。
🧠 四、管道初始化器(Pipeline)
public class WebSocketInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(8192));
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new WebSocketHandler());
}
}
解釋:
HttpServerCodec:HTTP 編解碼。HttpObjectAggregator:聚合 HTTP 消息為單一對象。WebSocketServerProtocolHandler:自動處理握手和心跳。WebSocketHandler:核心業務處理器。
💬 五、消息處理核心邏輯
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
private static final Map<String, Channel> userChannelMap = new ConcurrentHashMap<>();
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
String message = msg.text();
System.out.println("📩 收到消息:" + message);
ctx.channel().writeAndFlush(new TextWebSocketFrame("服務器收到:" + message));
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
String id = ctx.channel().id().asShortText();
userChannelMap.put(id, ctx.channel());
System.out.println("✅ 用户連接:" + id);
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx) {
userChannelMap.remove(ctx.channel().id().asShortText());
System.out.println("❎ 用户斷開連接");
}
public static void sendToAll(String msg) {
userChannelMap.values().forEach(ch -> ch.writeAndFlush(new TextWebSocketFrame(msg)));
}
}
解釋:
- 維護
userChannelMap保存用户連接。 sendToAll()用於廣播通知。- 每次客户端斷開時自動清理 Channel。
🛰 六、Spring Boot 消息控制接口
@RestController
@RequestMapping("/notify")
public class MessageController {
@PostMapping("/sendAll")
public String sendAll(@RequestParam String msg) {
WebSocketHandler.sendToAll("📢 系統通知:" + msg);
return "發送成功!";
}
}
解釋:
- 管理端通過 HTTP POST 請求
/notify/sendAll發送全員通知。 - 參數
msg為要發送的文本消息。
🧮 七、核心原理説明表
| 組件 | 作用 | 説明 |
|---|---|---|
| Netty Channel | 維護客户端連接 | 實現非阻塞 I/O 通信 |
| WebSocketFrame | 消息幀傳輸 | 支持文本、二進制、心跳等多類型 |
| EventLoopGroup | 線程調度 | boss 接收連接,worker 處理事件 |
| Spring Controller | 外部接口入口 | 支持 REST API 調用推送 |
🎯 八、運行流程圖
💡 九、關鍵優化建議
- 心跳機制:通過
IdleStateHandler定期檢測客户端狀態,防止假連接。 - 消息隊列整合:若業務量大,可結合 RabbitMQ/Kafka 實現異步推送。
- 用户綁定機制:通過用户ID與Channel關聯,實現點對點消息發送。
- 集羣支持:利用 Redis 發佈訂閲同步不同節點的 WebSocket 通道。
✅ 總結
此方案實現了一個可擴展、性能優越的實時消息通知系統。Spring Boot 提供業務接口,Netty 負責底層高併發連接,WebSocket 實現實時通信。該結構既能支撐簡單通知,也能輕鬆擴展為企業級消息推送平台 🔥。