【Netty+WebSocket詳解】WebSocket全雙工通信與Netty的高效結合與實戰

一、 Netty網絡框架、WebSocket協議基礎

????????1.1 Netty網絡框架介紹

????????1.2?WebSocket簡介

????????1.3 WebSocket握手流程

二、為什么選擇Netty+WebSocket?

三、Netty+WebSocket與Spring WebSocket

????????3.1 架構層級對比

????????3.2 核心組件差異

????????3.3?協議支持深度

????????3.4?性能基準測試

????????3.5?開發效率對比

????????3.6?典型應用場景

????????3.7 集成生態對比?編輯

四、基于Netty+WebSocket構建高性能實時通信系統

????????4.1 技術選型

????????4.2?pom.xml核心依賴

????????4.3?Netty服務的啟動類(服務器)

????????4.4 WebSocket初始化器

????????4.5 心跳處理類

????????4.6?消息處理器

????????4.7 Vue2 WebSocket連接核心代碼

五、總結


一、 Netty網絡框架、WebSocket協議基礎

1.1 Netty網絡框架介紹

參考我的另一篇文章:【Netty框架全解析】:從基礎概念到高階實踐,從零玩轉高性能網絡框架!-CSDN博客

1.2?WebSocket簡介

WebSocket是一種在單個TCP連接上進行全雙工通信的協議,解決了HTTP協議的半雙工和輪詢效率低的問題。其核心特點:

全雙工:客戶端和服務端可同時發送數據。

持久連接:一次握手后保持長連接。

低延遲:無需頻繁建立連接。

1.3 WebSocket握手流程

客戶端發起HTTP請求:包含Upgrade:websocket頭。

服務端響應101狀態碼:表示協議切換成功。

數據幀傳輸:后續通信通過二進制幀(Frame)進行。

握手請求示例

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13

握手響應示例

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=

二、為什么選擇Netty+WebSocket?

在實時通信(IM)場景中,低延遲、高并發、長連接是核心需求。Netty作為高性能網絡框架,結合WebSocket協議,能夠完美滿足這些要求:

全雙工通信:WebSocket支持服務端主動推送,告別HTTP輪詢

低延遲:Netty的Reactor線程模型+零拷貝技術,輕松支撐10萬級并發

協議靈活:可擴展支持自定義二進制協議

本文將帶你從零開始實現一個完整的IM系統,涵蓋消息收發、用戶在線狀態管理、心跳檢測等核心功能,并提供可運行的完整代碼

三、Netty+WebSocket與Spring WebSocket

3.1 架構層級對比

3.2 核心組件差異

Netty核心模塊

// 典型Netty WebSocket配置
pipeline.addLast(new HttpServerCodec()); // HTTP編解碼
pipeline.addLast(new HttpObjectAggregator(65536)); // 聚合HTTP請求
pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); // 協議升級
pipeline.addLast(new CustomFrameHandler()); // 自定義業務處理

Spring核心模塊

// 典型Spring配置
@Configuration
@EnableWebSocket
public class Config implements WebSocketConfigurer {void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myHandler(), "/ws");}
}

3.3?協議支持深度

3.4?性能基準測試

3.5?開發效率對比

3.6?典型應用場景

Netty更適合

游戲服務器(需要自定義二進制協議)

金融級交易系統(微秒級延遲要求)

IoT設備接入(海量長連接管理)

Spring WebSocket更適合

企業級消息通知系統

實時協作應用(如在線文檔)

需要快速集成Spring Security的場景

3.7 集成生態對比

四、基于Netty+WebSocket構建高性能實時通信系統

4.1 技術選型

Java?8+、Netty?4.x、WebSocket協議、Maven

4.2?pom.xml核心依賴

<dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.86.Final</version></dependency>
</dependencies>

4.3?Netty服務的啟動類(服務器)

/*** ChatServer: Netty 服務的啟動類(服務器)*/
public class ChatServer {public static void main(String[] args) throws Exception {// 定義主從線程組// 定義主線程池,用于接受客戶端的連接,但是不做任何處理,比如老板會談業務,拉到業務就會交給下面的員工去做了EventLoopGroup bossGroup = new NioEventLoopGroup();// 定義從線程池,處理主線程池交過來的任務,公司業務員開展業務,完成老板交代的任務EventLoopGroup workerGroup = new NioEventLoopGroup();try {// 構建Netty服務器ServerBootstrap server = new ServerBootstrap();     // 服務的啟動類server.group(bossGroup, workerGroup)                // 把主從線程池組放入到啟動類中.channel(NioServerSocketChannel.class)      // 設置Nio的雙向通道.childHandler(new WSServerInitializer());   // 設置處理器,用于處理workerGroup// 啟動server,并且綁定端口號875,同時啟動方式為"同步"ChannelFuture channelFuture = server.bind(875).sync();// 請求:http://127.0.0.1:875// 監聽關閉的channelchannelFuture.channel().closeFuture().sync();} finally {// 優雅的關閉線程池組bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}}

4.4 WebSocket初始化器

/*** 初始化器,channel注冊后,會執行里面的相應的初始化方法*/
public class WSServerInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel channel) throws Exception {// 通過SocketChannel獲得對應的管道ChannelPipeline pipeline = channel.pipeline();/*** 通過管道,添加handler處理器*/// HttpServerCodec 是由netty自己提供的助手類,此處可以理解為管道中的攔截器// 當請求到服務端,我們需要進行做解碼,相應到客戶端做編碼// websocket 基于http協議,所以需要有http的編解碼器pipeline.addLast(new HttpServerCodec());// 添加對大數據流的支持pipeline.addLast(new ChunkedWriteHandler());// 對httpMessage進行聚合,聚合成為FullHttpRequest或FullHttpResponse// 幾乎在netty的編程中,都會使用到此handlerpipeline.addLast(new HttpObjectAggregator(1024 * 64));// ==================== 以上是用于支持http協議相關的handler ====================// ==================== 增加心跳支持 start ====================// 針對客戶端,如果在5小時沒有向服務端發送讀寫心跳(ALL),則主動斷開連接// 如果是讀空閑或者寫空間,不做任何處理(參數分別對應讀空閑、寫空閑、讀寫空閑秒數)pipeline.addLast(new IdleStateHandler(8,10,300 * 60));pipeline.addLast(new HeartBeatHandler());// ==================== 增加心跳支持 end ====================// ==================== 以下是用于支持websocket ====================/*** WebSocket 服務器處理的協議,用于指定給客戶端連接的時候訪問路由: /ws* 此Handler會幫我們處理一些比較復雜的繁重的操作* 會處理一些握手操作:handShaking(close,ping,pong)ping + pong = 心跳* 對于WebSocket來說,數據都是以frames(幀)進行傳輸的,不同的數據類型所對應的frames(幀)也都不同*/pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));// 添加自定義的助手類pipeline.addLast(new ChatHandler());}
}

4.5 心跳處理類

/*** 創建心跳助手類*/
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {// 判斷evt是否是IdleStateEvent(空閑事件狀態,包含 讀空閑/寫空閑/讀寫空閑)if (evt instanceof IdleStateEvent) {IdleStateEvent event = (IdleStateEvent)evt;if (event.state() == IdleState.READER_IDLE) {// System.out.println("進入讀空閑...");} else if (event.state() == IdleState.WRITER_IDLE) {// System.out.println("進入寫空閑...");} else if (event.state() == IdleState.ALL_IDLE) {Channel channel = ctx.channel();// 關閉無用的channel,以防資源浪費channel.close();}}}
}

4.6?消息處理器

/*** 創建自定義助手類*/
// SimpleChannelInboundHandler: 對于請求來說,相當于入站(入境)
// TextWebSocketFrame: 用于為websocket專門處理的文本數據對象,Frame是數據(消息)的載體
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {// 存儲所有連接的Channelprivate static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void channelActive(ChannelHandlerContext ctx) {clients.add(ctx.channel());System.out.println("客戶端連接: " + ctx.channel().id());}@Overridepublic void channelInactive(ChannelHandlerContext ctx) {clients.remove(ctx.channel());System.out.println("客戶端斷開: " + ctx.channel().id());}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {String msg = frame.text();System.out.println("收到消息: " + msg);// 方案1:廣播給所有客戶端clients.writeAndFlush(new TextWebSocketFrame("[廣播] " + msg));// 方案2:轉發給特定客戶端(示例邏輯)if (msg.startsWith("@")) {forwardToTargetClient(msg);}}private void forwardToTargetClient(String msg) {String targetId = msg.substring(1, msg.indexOf(" "));String content = msg.substring(msg.indexOf(" ") + 1);clients.stream().filter(ch -> ch.id().asShortText().equals(targetId)).findFirst().ifPresent(ch -> ch.writeAndFlush(new TextWebSocketFrame("[私信] " + content)));}/*** 發生異常并且捕獲,移除channel*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {clients.remove(ctx.channel());ctx.close();cause.printStackTrace();}
}

4.7 Vue2 WebSocket連接核心代碼

// src/utils/websocket.js
export default class SocketService {static instance = nullstatic get Instance() {if (!this.instance) {this.instance = new SocketService()}return this.instance}// 連接狀態標記connected = falsews = null// 初始化連接connect() {if (!this.connected) {this.ws = new WebSocket('ws://localhost:875')this.ws.onopen = () => {this.connected = trueconsole.log('Netty連接成功')}this.ws.onmessage = (msg) => {console.log('收到消息:', msg.data)// 這里可以觸發Vuex的action處理消息}this.ws.onclose = () => {this.connected = falseconsole.log('Netty連接關閉')}this.ws.onerror = (err) => {console.error('連接錯誤:', err)}}}// 發送消息send(data) {if (this.connected) {this.ws.send(JSON.stringify(data))} else {console.error('尚未建立連接')}}
}
<template><div><button @click="connect">連接Netty</button><button @click="sendTestMsg">發送測試消息</button><div v-for="(msg, index) in messages" :key="index">{{ msg }}</div></div>
</template><script>
import SocketService from '@/utils/websocket'export default {data() {return {messages: []}},methods: {connect() {SocketService.Instance.connect()},sendTestMsg() {SocketService.Instance.send({type: 'test',content: 'Hello Netty!',timestamp: Date.now()})}},mounted() {// 可選:組件加載時自動連接// this.connect()}
}
</script>

4.8 Spring WebSocket實現簡單通信系統

參考我的文章:【Spring WebSocket詳解】Spring WebSocket從入門到實戰-CSDN博客

五、總結

本文通過Netty框架實現了基于WebSocket協議的簡單通信系統,覆蓋了從基礎握手、消息處理到心跳檢測的全流程。實際開發中還需考慮安全性(如WSS加密)、跨域處理、消息持久化等高級功能。如果你對上文有什么其他理解或者問題歡迎評論區留言討論!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90564.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90564.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90564.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

5、Vue中使用Cesium實現交互式折線繪制詳解

引言 Cesium是一款強大的開源3D地理信息可視化引擎&#xff0c;廣泛應用于數字地球、地圖可視化等領域。在Vue項目中集成Cesium可以快速構建高性能的地理信息應用。本文將詳細介紹如何在Vue項目中實現交互式折線繪制功能&#xff0c;包括頂點添加、臨時繪制、距離計算等核心功…

mysql實戰之主從復制

原理圖理論&#xff1a;一、配置準備每臺主機都安裝mysql對每臺主機都進行對時操作&#xff0c;減少時間誤差[rooteveryone ~]# timedatectl set-timezone Asia/Shanghai [rooteveryone ~]# systemctl restart chronyd.service 對每臺主機都進行關閉防火墻、上下文等&#xff0…

中望CAD2026亮點速遞(5):【相似查找】高效自動化識別定位

本文為CAD芯智庫整理&#xff0c;未經允許請勿復制、轉載&#xff01;原文轉自&#xff1a;www.xwzsoft.com/h-nd-594.html CAD的相似查找功能主要應用于需要重復操作、標準化控制、一致性檢查或復雜模式識別的場景&#xff0c;通過圖形相似度算法&#xff0c;快速找到匹配的圖…

國產化條碼類庫Spire.Barcode教程:使用 C# 讀取二維碼(QR Code)——從圖片或數據流解析

二維碼已成為現代應用的常見組成部分&#xff0c;廣泛應用于用戶身份驗證、移動支付、商品包裝和活動票務等場景。很多使用 C# 開發的系統需要從圖像或掃描件中提取二維碼信息&#xff0c;因此掌握二維碼識別技術顯得尤為重要。 為滿足這類需求&#xff0c;開發者需要一種既可…

IPSAN 共享存儲詳解:架構、優化與落地實踐指南

一、IPSAN 技術定位與核心價值核心價值對比矩陣&#xff1a;維度IPSANFC-SAN實現方案成本端口成本$500端口成本$2000復用IP網絡設備傳輸距離跨地域&#xff08;VPN/專線&#xff09;≤10公里兩地三中心架構運維效率SNMP/CLI管理Zone/ALPA管理自動化運維工具鏈協議標準IETF RFC …

【衛星語音】基于神經網絡的低碼率語音編解碼(ULBC)方案架構分析:以SoundStream為例

摘要 隨著深度學習技術的快速發展&#xff0c;基于神經網絡的音頻編解碼技術已成為下一代音頻壓縮的重要研究方向。本文以Google提出的SoundStream為核心分析對象&#xff0c;深入探討其在低碼率語音編解碼領域的創新架構設計和關鍵技術突破。SoundStream通過全卷積編解碼器網絡…

技術面試問題總結一

MySQL的幾種鎖機制一、從鎖的粒度角度劃分表級鎖機制&#xff1a;它是對整張表進行鎖定的一種鎖。當一個事務對表執行寫操作時&#xff0c;會獲取寫鎖&#xff0c;在寫鎖持有期間&#xff0c;其他事務無法對該表進行讀寫操作&#xff1b;而當事務執行讀操作時&#xff0c;會獲取…

Python(一)

基本語法&#xff1a;變量&#xff0c;語法變量類型&#xff1a;不同于Java&#xff0c;C語言&#xff0c;C&#xff0c;Python在創建一個變量的時候&#xff0c;不需要聲明變量類型&#xff0c;由編譯器自行識別Python語句在只有一個語句的時候語句末尾不需要分號&#xff0c;…

Adaptive AUTOSAR中的Firewall技術:智能汽車網絡安全架構的核心

1 防火墻技術基礎 1.1 定義與演進歷程 防火墻(Firewall)作為一種位于內部網絡與外部網絡之間的網絡安全系統,本質上是依照特定規則允許或限制數據傳輸的信息安全防護機制。在汽車電子電氣架構從分布式向集中式轉變的背景下,防火墻技術已從傳統的IT領域深度融入Adaptive A…

android閃光燈源碼分析

目錄 一、APP層源碼分析 二&#xff0c;framework層代碼分析 ???????2.1 binder溯源 這幾天擼了android11 aosp閃光燈源碼&#xff0c;本著前人栽樹后人乘涼的原則&#xff0c;有志于android系統開發的新同學們提供一盞明燈&#xff0c;照亮你們前行。 本人擼代碼風格&…

文心一言4.5開源部署指南及文學領域測評

&#x1f4dd;個人主頁&#xff1a;哈__ 期待您的關注 目錄 一、引言 二、文心一言開源模型 2.1 MoE架構 2.2 文心一言MoE架構 三、文心一言稠密模型部署 3.1 產品選擇 3.2 環境選擇 3.3 Python3.12安裝 3.3 PaddlePaddle-GPU安裝 3.4 FastDeploy-GPU安裝 ?編輯3.…

深入探討 C++ 中的浮點數數據類型

核心概念&#xff1a;IEEE 754 標準 C 中的浮點數&#xff08;float, double, long double&#xff09;在絕大多數現代系統上遵循 IEEE 754 標準。這個標準定義了浮點數在內存中的二進制表示方式、運算規則、特殊值&#xff08;如無窮大、NaN&#xff09;等。數據類型與精度 fl…

相機:以鼠標點為中心縮放(使用OpenGL+QT開發三維CAD)

很多軟件中&#xff08;Auto CAD、ODA等&#xff09;支持以鼠標點為中心進行放縮操作&#xff0c;有什么黑科技嗎&#xff1f; 本章節為相機原理和實現的補充內容&#xff0c;支持鼠標放縮時以鼠標點為中心進行放縮。 對應視頻課程已上線&#xff0c;歡迎觀看和支持~ https:…

??XAMPP安全升級指南:修復CVE-2024-4577漏洞,從PHP 8.2.12升級至PHP 8.4.10??

??1. 背景與漏洞概述?? 近期,PHP官方披露了一個高危漏洞 ??CVE-2024-4577??,該漏洞影響PHP 8.2.x及更早版本,可能導致遠程代碼執行(RCE)或信息泄露。由于XAMPP默認捆綁的PHP版本(如8.2.12)可能受此漏洞影響,建議用戶盡快升級至最新的??PHP 8.4.10??(或官…

ES 壓縮包安裝

以下是 Elasticsearch (ES) 通過 .tar.gz 壓縮包安裝的詳細步驟&#xff08;適用于 Linux/macOS 系統&#xff09;&#xff1a; 1. 準備工作 1.1 檢查系統依賴 Java 環境&#xff1a;ES 需要 JDK&#xff0c;推薦 OpenJDK 11/17&#xff08;ES 7.x/8.x 兼容版本&#xff09;。…

RoboRefer:面向機器人視覺-語言模型推理的空間參考

25年6月來自北航、北大和北京智源的論文“RoboRefer: Towards Spatial Referring with Reasoning in Vision-Language Models for Robotics”。 空間參考是實體機器人與三維物理世界交互的基本能力。然而&#xff0c;即使有了強大的預訓練視覺-語言模型 (VLM)&#xff0c;近期方…

【Unity】MiniGame編輯器小游戲(十)連連看【Link】

更新日期:2025年7月9日。 項目源碼:獲取項目源碼 索引 連連看【Link】一、游戲最終效果二、玩法簡介三、正式開始1.定義游戲窗口類2.規劃游戲窗口、視口區域3.方塊 Block①.定義方塊類②.生成方塊所有類型③.生成連連看棋盤④.繪制方塊陣列4.連線 Line①.點擊方塊連線②.嘗試…

Enable ADB Debugging Before Connect

If you don’t enable Developer Options and turn on USB Debugging before plugging in the cable, adb devices won’t detect the phone because the Android system doesn’t trust the connection yet. Here’s what you need to do step-by-step to fix this:? 1. Enab…

從互聯網電腦遷移Dify到內網部署Dify方法記錄

一、在互聯網電腦上準備遷移文件1. 保存 Docker 鏡像# 獲取所有 Dify 相關鏡像&#xff08;根據實際容器名調整&#xff09; docker ps --filter "namedify" --format "{{.Image}}" | sort -u > dify-images.list# 保存鏡像為 .tar 文件 docker save $(…

【EGSR2025】材質+擴散模型+神經網絡相關論文整理隨筆(一)

MatSwap: Light-aware material transfers in images介紹任務&#xff1a;輸入一張拍攝圖像、示例材質紋理圖像&#xff08;這里跟BRDF無關&#xff0c;通常我們講到材質一般指的是SVBRDF&#xff0c;但是這里的材質指的只是紋理&#xff09;、用戶為拍攝圖像指定的遮罩區域&am…