JAVA 日常開(kāi)發(fā)中Websocket示例詳解
JAVA |日常開(kāi)發(fā)中Websocket詳解
,WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,它在Web應(yīng)用中實(shí)現(xiàn)了客戶(hù)端與服務(wù)器之間的實(shí)時(shí)數(shù)據(jù)傳輸。與HTTP不同,WebSocket在建立連接后,客戶(hù)端和服務(wù)器都可以隨時(shí)向?qū)Ψ桨l(fā)送數(shù)據(jù),而無(wú)需像HTTP那樣每次請(qǐng)求都需要建立新的連接。這使得WebSocket非常適合需要實(shí)時(shí)通信的場(chǎng)景,如在線(xiàn)聊天、實(shí)時(shí)通知、股票行情推送等。本文將詳細(xì)介紹Java開(kāi)發(fā)中WebSocket的使用,包括基本概念、Java API、使用示例以及注意事項(xiàng)。
前言
在數(shù)字浪潮洶涌澎湃的時(shí)代,程序開(kāi)發(fā)宛如一座神秘而宏偉的魔法城堡,矗立在科技的浩瀚星空中。代碼的字符,似那閃爍的星辰,按照特定的軌跡與節(jié)奏,組合、交織、碰撞,即將開(kāi)啟一場(chǎng)奇妙且充滿(mǎn)無(wú)限可能的創(chuàng)造之旅。當(dāng)空白的文檔界面如同深邃的宇宙等待探索,程序員們則化身無(wú)畏的星辰開(kāi)拓者,指尖在鍵盤(pán)上輕舞,準(zhǔn)備用智慧與邏輯編織出足以改變世界運(yùn)行規(guī)則的程序畫(huà)卷,在 0 和 1 的二進(jìn)制世界里,鐫刻下屬于人類(lèi)創(chuàng)新與突破的不朽印記。
一、Websocket 概述
1.1 定義
Websocket 是一種在單個(gè) TCP 連接上進(jìn)行全雙工通信的協(xié)議。它允許客戶(hù)端和服務(wù)器之間進(jìn)行實(shí)時(shí)的、雙向的數(shù)據(jù)傳輸,與傳統(tǒng)的 HTTP 請(qǐng)求 - 響應(yīng)模式不同,HTTP 是單向的,客戶(hù)端請(qǐng)求,服務(wù)器響應(yīng)后連接就關(guān)閉,而 Websocket 保持連接打開(kāi),以便隨時(shí)交換數(shù)據(jù)。
例如,在一個(gè)實(shí)時(shí)聊天應(yīng)用中,Websocket 可以讓客戶(hù)端(如瀏覽器)和服務(wù)器之間實(shí)時(shí)地發(fā)送和接收聊天消息,而不需要像傳統(tǒng)的 HTTP 輪詢(xún)那樣頻繁地發(fā)送請(qǐng)求來(lái)檢查是否有新消息。
1.2 優(yōu)勢(shì)
實(shí)時(shí)性高:能夠?qū)崿F(xiàn)服務(wù)器和客戶(hù)端之間的實(shí)時(shí)通信,數(shù)據(jù)可以即時(shí)地在雙方之間傳遞,減少了延遲。這對(duì)于需要實(shí)時(shí)更新數(shù)據(jù)的應(yīng)用場(chǎng)景,如股票交易平臺(tái)、在線(xiàn)游戲等非常關(guān)鍵。
高效節(jié)能:相較于傳統(tǒng)的 HTTP 輪詢(xún)(客戶(hù)端定時(shí)向服務(wù)器發(fā)送請(qǐng)求來(lái)獲取最新信息),Websocket 避免了頻繁建立和斷開(kāi)連接的開(kāi)銷(xiāo),從而節(jié)省了網(wǎng)絡(luò)資源和服務(wù)器資源,提高了效率。
跨平臺(tái)支持:Websocket 協(xié)議是基于 TCP 協(xié)議的,并且在現(xiàn)代瀏覽器和大多數(shù)服務(wù)器環(huán)境中都有良好的支持,這使得它可以方便地用于開(kāi)發(fā)跨平臺(tái)的實(shí)時(shí)應(yīng)用。
二、Websocket 協(xié)議基礎(chǔ)
2.1 握手過(guò)程
Websocket 協(xié)議在建立連接時(shí)需要進(jìn)行握手。客戶(hù)端首先向服務(wù)器發(fā)送一個(gè) HTTP 請(qǐng)求,這個(gè)請(qǐng)求中包含一些特殊的頭部信息,用于表明這是一個(gè) Websocket 請(qǐng)求。例如,請(qǐng)求頭中包含Upgrade: websocket和Connection: Upgrade字段,用于請(qǐng)求將協(xié)議從 HTTP 升級(jí)到 Websocket。
服務(wù)器收到請(qǐng)求后,如果支持 Websocket 協(xié)議并且同意升級(jí),會(huì)返回一個(gè)響應(yīng),其中包含101 Switching Protocols狀態(tài)碼,表示協(xié)議切換成功,之后雙方就建立了 Websocket 連接。
2.2 消息格式
Websocket 消息主要有兩種格式:文本格式和二進(jìn)制格式。消息以幀(frame)為單位進(jìn)行傳輸,一個(gè)完整的消息可以由一個(gè)或多個(gè)幀組成。
文本消息以 UTF - 8 編碼進(jìn)行傳輸,方便處理文本數(shù)據(jù),如聊天消息等。二進(jìn)制格式則適用于傳輸圖像、音頻、視頻等二進(jìn)制數(shù)據(jù)。
2.3 數(shù)據(jù)傳輸方式
全雙工通信意味著客戶(hù)端和服務(wù)器都可以主動(dòng)發(fā)送消息。在連接建立后,任何一方都可以隨時(shí)發(fā)送數(shù)據(jù),并且不需要等待對(duì)方的請(qǐng)求。例如,服務(wù)器可以主動(dòng)向客戶(hù)端推送實(shí)時(shí)的股票價(jià)格變化,同時(shí)客戶(hù)端也可以向服務(wù)器發(fā)送交易指令。
三、Java 中使用 Websocket
3.1 Java WebSocket API(JSR - 356)
簡(jiǎn)介:Java 提供了 WebSocket API 來(lái)方便地在 Java 應(yīng)用中實(shí)現(xiàn) Websocket 功能。這個(gè) API 定義了客戶(hù)端和服務(wù)器端的接口,使得開(kāi)發(fā)者可以輕松地構(gòu)建 Websocket 應(yīng)用。
服務(wù)器端實(shí)現(xiàn)示例:
首先,創(chuàng)建一個(gè)@ServerEndpoint注解的類(lèi)來(lái)表示 Websocket 服務(wù)器端點(diǎn)。
import javax.websocket.OnMessage; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/chat") public class ChatServer { @OnMessage public String onMessage(String message) { // 簡(jiǎn)單的消息處理,例如將消息轉(zhuǎn)換為大寫(xiě) return message.toUpperCase(); } }
在上述示例中,@ServerEndpoint("/chat")注解定義了 Websocket 服務(wù)器端點(diǎn)的路徑為/chat。@OnMessage注解標(biāo)記的方法會(huì)在收到消息時(shí)被調(diào)用,這里只是簡(jiǎn)單地將收到的消息轉(zhuǎn)換為大寫(xiě)并返回。
客戶(hù)端實(shí)現(xiàn)示例:
客戶(hù)端需要?jiǎng)?chuàng)建一個(gè)WebSocketContainer來(lái)建立連接并發(fā)送和接收消息。
import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; import java.net.URI; public class ChatClient { public static void main(String[] args) { try { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); String uri = "ws://localhost:8080/chat"; javax.websocket.Session session = container.connectToServer(ChatClientEndpoint.class, new URI(uri)); // 發(fā)送消息 session.getBasicRemote().sendText("Hello"); // 接收消息 String response = session.getBasicRemote().receiveText(); System.out.println("收到回復(fù): " + response); } catch (Exception e) { e.printStackTrace(); } } }
在這個(gè)客戶(hù)端示例中,首先獲取WebSocketContainer,然后通過(guò)connectToServer方法連接到服務(wù)器端點(diǎn)。之后可以使用sendText發(fā)送消息,使用receiveText接收消息。
3.2 第三方庫(kù)(如 Tyrus)
簡(jiǎn)介:Tyrus 是一個(gè)流行的 Websocket 實(shí)現(xiàn)庫(kù),它提供了豐富的功能和更好的性能。它是 Java EE 規(guī)范的參考實(shí)現(xiàn),支持 JSR - 356 標(biāo)準(zhǔn)。
示例代碼(服務(wù)器端):
添加 Tyrus 依賴(lài)到項(xiàng)目(以 Maven 為例)。
<dependency> <groupId>org.glassfish.tyrus - servlet</groupId> <artifactId>tyrus - servlet</artifactId> <version>1.15</version> </dependency>
創(chuàng)建服務(wù)器端點(diǎn)類(lèi)。
import org.glassfish.tyrus.server.Server; public class TyrusChatServer { public static void main(String[] args) { Server server = new Server("localhost", 8080, "/", null, ChatServerEndpoint.class); try { server.start(); System.out.println("服務(wù)器已啟動(dòng)"); // 保持服務(wù)器運(yùn)行 Thread.sleep(Long.MAX_VALUE); } catch (Exception e) { e.printStackTrace(); } finally { server.stop(); } } }
其中ChatServerEndpoint類(lèi)可以類(lèi)似于前面 JSR - 356 中的服務(wù)器端點(diǎn)類(lèi)定義,用于處理消息。
示例代碼(客戶(hù)端):
同樣需要添加 Tyrus 客戶(hù)端依賴(lài)。
<dependency> <groupId>org.glassfish.tyrus - client</groupId> <artifactId>tyrus - client</artifactId> <version>1.15</version> </dependency>
客戶(hù)端連接和消息發(fā)送接收示例。
import org.glassfish.tyrus.client.ClientManager; import javax.websocket.Session; import java.io.IOException; import java.net.URI; public class TyrusChatClient { public static void main(String[] args) { try { ClientManager clientManager = new ClientManager(); String uri = "ws://localhost:8080/chat"; Session session = clientManager.connectToServer(ChatClientEndpoint.class, new URI(uri)); // 發(fā)送消息 session.getBasicRemote().sendText("Hello"); // 接收消息 String response = session.getBasicRemote().receiveText(); System.out.println("收到回復(fù): " + response); } catch (Exception e) { e.printStackTrace(); } } }
四、應(yīng)用場(chǎng)景
4.1 實(shí)時(shí)聊天應(yīng)用
這是 Websocket 最典型的應(yīng)用場(chǎng)景之一。用戶(hù)在瀏覽器中打開(kāi)聊天界面,通過(guò) Websocket 與服務(wù)器建立連接。當(dāng)用戶(hù)發(fā)送聊天消息時(shí),消息通過(guò) Websocket 即時(shí)傳輸?shù)椒?wù)器,服務(wù)器再將消息轉(zhuǎn)發(fā)給其他相關(guān)用戶(hù)的客戶(hù)端,實(shí)現(xiàn)實(shí)時(shí)聊天功能。
4.2 實(shí)時(shí)數(shù)據(jù)推送(如股票行情、體育賽事比分)
對(duì)于需要實(shí)時(shí)更新數(shù)據(jù)的應(yīng)用,如金融領(lǐng)域的股票行情監(jiān)控應(yīng)用,Websocket 可以讓服務(wù)器在股票價(jià)格發(fā)生變化時(shí),立即將最新價(jià)格推送給客戶(hù)端。體育賽事比分更新也是類(lèi)似的,觀眾可以在瀏覽器中實(shí)時(shí)看到比分的變化,而不需要手動(dòng)刷新頁(yè)面。
4.3 在線(xiàn)游戲
在多人在線(xiàn)游戲中,Websocket 用于實(shí)時(shí)同步玩家的操作和游戲狀態(tài)。例如,在一個(gè)多人競(jìng)技游戲中,玩家的移動(dòng)、攻擊等操作可以通過(guò) Websocket 即時(shí)傳輸?shù)椒?wù)器,服務(wù)器再將這些信息廣播給其他玩家,確保游戲的實(shí)時(shí)性和公平性。
結(jié)束語(yǔ)
親愛(ài)的朋友,無(wú)論前路如何漫長(zhǎng)與崎嶇,都請(qǐng)懷揣夢(mèng)想的火種,因?yàn)樵谏畹膹V袤星空中,總有一顆屬于你的璀璨星辰在熠熠生輝,靜候你抵達(dá)。
愿你在這紛繁世間,能時(shí)常收獲微小而確定的幸福,如春日微風(fēng)輕拂面龐,所有的疲憊與煩惱都能被溫柔以待,內(nèi)心永遠(yuǎn)充盈著安寧與慰藉。
至此,文章已至尾聲,而您的故事仍在續(xù)寫(xiě),不知您對(duì)文中所敘有何獨(dú)特見(jiàn)解?期待您在心中與我對(duì)話(huà),開(kāi)啟思想的新交流。
到此這篇關(guān)于JAVA 日常開(kāi)發(fā)中Websocket示例詳解的文章就介紹到這了,更多相關(guān)java Websocket內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中使用WebSocket的幾種方式
- Java實(shí)現(xiàn)使用Websocket發(fā)送消息詳細(xì)代碼舉例
- 如何在Java中使用WebSocket協(xié)議
- springboot整合websocket后啟動(dòng)報(bào)錯(cuò)(javax.websocket.server.ServerContainer not available)
- Java WebSocket客戶(hù)端接收大量數(shù)據(jù)的三種方案
- 使用Java WebSocket獲取客戶(hù)端IP地址的示例代碼
- Java中實(shí)現(xiàn)WebSocket方法詳解
- 教你如何使用Java實(shí)現(xiàn)WebSocket
- 一步步教你如何使用Java實(shí)現(xiàn)WebSocket
- java后端+前端使用WebSocket實(shí)現(xiàn)消息推送的詳細(xì)流程
相關(guān)文章
Java多線(xiàn)程之線(xiàn)程池七個(gè)參數(shù)詳解
這篇文章主要介紹了Java多線(xiàn)程之線(xiàn)程池七個(gè)參數(shù)詳解,文中有很詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下2021-04-04IDEA設(shè)置生成帶注釋的getter和setter的圖文教程
通常我們用idea默認(rèn)生成的getter和setter方法是不帶注釋的,當(dāng)然,我們同樣可以設(shè)置idea像MyEclipse一樣生成帶有Javadoc的模板,具體設(shè)置方法,大家參考下本文2018-05-05MyBatis自定義類(lèi)型轉(zhuǎn)換器實(shí)現(xiàn)加解密
這篇文章主要介紹了MyBatis自定義類(lèi)型轉(zhuǎn)換器實(shí)現(xiàn)加解密的相關(guān)資料,需要的朋友可以參考下2016-07-07Java屬性文件操作之Properties與ResourceBundle詳解
這篇文章主要介紹了Java屬性文件操作之Properties與ResourceBundle詳解,兩個(gè)類(lèi)都可以讀取屬性文件中以key/value形式存儲(chǔ)的鍵值對(duì),ResourceBundle讀取屬性文件時(shí)操作相對(duì)簡(jiǎn)單,需要的朋友可以參考下2023-11-11springmvc下實(shí)現(xiàn)登錄驗(yàn)證碼功能示例
本篇文章主要介紹了springmvc下實(shí)現(xiàn)登錄驗(yàn)證碼功能示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02java報(bào)錯(cuò)非法的前向引用問(wèn)題
這篇文章主要介紹了java報(bào)錯(cuò)非法的前向引用問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-055種必會(huì)的Java異步調(diào)用轉(zhuǎn)同步的方法你會(huì)幾種
這篇文章主要介紹了5種必會(huì)的Java異步調(diào)用轉(zhuǎn)同步的方法你會(huì)幾種,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12