SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐
一、后端pom.xml引入依賴(lài)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
二、啟動(dòng)類(lèi)注入Bean
@SpringBootApplication public class TtSdemoApplication { public static void main(String[] args) { SpringApplication.run(TtSdemoApplication.class, args); } @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
三、編寫(xiě)WebSocket類(lèi)
package com.zj.ttsdemo.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; /** * Created by * * @Author: JoyceZhang * @Date: 2023/05/25/15:28 * @Description: */ @Slf4j @ServerEndpoint(value="/websocket") @Component public class Websocket { private static Session[] sessionContainer = new Session[2]; /** * A,B與服務(wù)器建立連接 */ @OnOpen public void onOpen(Session session) { if (sessionContainer[0] == null && sessionContainer[1] == null) { sessionContainer[0] = session; log.info("a連接成功"); } else if (sessionContainer[0] != null && sessionContainer[1] == null) { sessionContainer[1] = session; log.info("b連接成功"); } else { log.info("連接失敗"); } } /** * 鏈接關(guān)閉 */ @OnClose public void onClose(Session session) { for(int i=0;i<sessionContainer.length;i++){ if(sessionContainer[i] == session){ sessionContainer[i] = null; log.info((i==0?"a":"b")+"斷開(kāi)連接"); } } } /** * 得到另一個(gè)session對(duì)象 */ private Session getOtherSession(Session session) { for(int i = 0; i<sessionContainer.length;i++){ if(session == sessionContainer[i]){ log.info("獲取到另一個(gè)session"); return sessionContainer[(i==0?1:0)]; } } return null; } /** * 向另一個(gè)session發(fā)送消息 */ @OnMessage public void sendMessage(String message,Session session) throws IOException{ Session otherSession = this.getOtherSession(session); log.info("發(fā)送消息"+message+"到"+(otherSession==sessionContainer[0]?"a":"b")); otherSession.getBasicRemote().sendText(message); } /** * 異常處理 */ @OnError public void onError(Session session, Throwable error) { log.error("發(fā)生錯(cuò)誤"); error.printStackTrace(); } }
四、編寫(xiě)測(cè)試頁(yè)面
在resource/static目錄下編寫(xiě)chat.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <input id = "text" type ="text"> <button onclick = "send()">Send</button> <button onclick = "closeWebSocket()">Close</button> <div id = "message"></div> </body> <script type="text/javascript"> var websocket = null; //判斷當(dāng)前瀏覽器是否支持WebSocket if('WebSocket' in window){ websocket = new WebSocket("ws://localhost:8083/websocket"); } else{ alert('Not support websocket') } //連接發(fā)生錯(cuò)誤的回調(diào)方法 websocket.onerror = function(){ setMessageInnerHTML("服務(wù)器通信故障"); }; //連接成功建立的回調(diào)方法 websocket.onopen = function(event){ setMessageInnerHTML("與服務(wù)器通信成功"); } //接收到消息的回調(diào)方法 websocket.onmessage = function(event){ setMessageInnerHTML(event.data); } //連接關(guān)閉的回調(diào)方法 websocket.onclose = function(){ setMessageInnerHTML("WebSocket連接關(guān)閉"); } //監(jiān)聽(tīng)窗口關(guān)閉事件,當(dāng)窗口關(guān)閉時(shí),主動(dòng)去關(guān)閉websocket連接,防止連接還沒(méi)斷開(kāi)就關(guān)閉窗口,server端會(huì)拋異常。 window.onbeforeunload = function(){ websocket.close(); } //將消息顯示在網(wǎng)頁(yè)上 function setMessageInnerHTML(innerHTML){ document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //關(guān)閉連接 function closeWebSocket(){ websocket.close(); } //發(fā)送消息 function send(){ var message = document.getElementById('text').value; websocket.send(message); } </script> </html>
五、通信測(cè)試
【IT老齊238】十分鐘上手WebSocket全雙工通信協(xié)議_嗶哩嗶哩_bilibili
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)WebSocket全雙工通信的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot WebSocket全雙工通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot實(shí)現(xiàn)人臉識(shí)別與WebSocket長(zhǎng)連接的實(shí)現(xiàn)代碼
- SpringBoot+WebSocket實(shí)現(xiàn)IM及時(shí)通訊的代碼示例
- SpringBoot+websocket實(shí)現(xiàn)消息對(duì)話(huà)功能
- SpringBoot 整合WebSocket 前端 uniapp 訪(fǎng)問(wèn)的詳細(xì)方法
- Springboot+WebSocket+Netty實(shí)現(xiàn)在線(xiàn)聊天/群聊系統(tǒng)
- SpringBoot集成WebSocket的兩種方式(JDK內(nèi)置版和Spring封裝版)
- SpringBoot中使用WebSocket的教程分享
- 使用WebSocket+SpringBoot+Vue搭建簡(jiǎn)易網(wǎng)頁(yè)聊天室的實(shí)現(xiàn)代碼
- SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端發(fā)送消息的實(shí)例代碼
- Springboot+WebSocket實(shí)現(xiàn)在線(xiàn)聊天功能
- springboot中websocket簡(jiǎn)單實(shí)現(xiàn)
- Spring Boot中的WebSocketMessageBrokerConfigurer接口使用
相關(guān)文章
springboot整合sentinel接口熔斷的實(shí)現(xiàn)示例
為了防止慢接口導(dǎo)致的服務(wù)阻塞,可以通過(guò)添加熔斷處理來(lái)避免應(yīng)用的大量工作線(xiàn)程陷入阻塞,保證其他接口的正常運(yùn)行,本文介紹了如何使用Spring Boot與Sentinel進(jìn)行接口熔斷的配置與實(shí)現(xiàn),感興趣的可以了解一下2024-09-09Spring中過(guò)濾器(Filter)和攔截器(Interceptor)的區(qū)別和聯(lián)系解析
在我們?nèi)粘5拈_(kāi)發(fā)中,我們經(jīng)常會(huì)用到Filter和Interceptor,這篇文章主要介紹了Spring中過(guò)濾器(Filter)和攔截器(Interceptor)的區(qū)別和聯(lián)系?,需要的朋友可以參考下2022-10-10SpringBoot返回統(tǒng)一的JSON標(biāo)準(zhǔn)格式實(shí)現(xiàn)步驟
這篇文章主要介紹了SpringBoot返回統(tǒng)一的JSON標(biāo)準(zhǔn)格式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08SpringBoot中統(tǒng)計(jì)方法耗時(shí)的七種實(shí)現(xiàn)方式小結(jié)
作為開(kāi)發(fā)者,我們經(jīng)常需要統(tǒng)計(jì)方法的執(zhí)行時(shí)間,以便找出性能瓶頸,優(yōu)化系統(tǒng)響應(yīng)速度,今天分享在SpringBoot框架中實(shí)現(xiàn)方法耗時(shí)統(tǒng)計(jì)的幾種方法,大家可以根據(jù)需求自行選擇2025-03-03java開(kāi)發(fā)RocketMQ生產(chǎn)者高可用示例詳解
這篇文章主要為大家介紹了java開(kāi)發(fā)RocketMQ生產(chǎn)者高可用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08JAVA SE包裝類(lèi)和泛型詳細(xì)介紹及說(shuō)明方法
這篇文章主要介紹了JAVA SE包裝類(lèi)和泛型的相關(guān)資料,包括基本數(shù)據(jù)類(lèi)型與包裝類(lèi)的對(duì)應(yīng)關(guān)系,以及裝箱和拆箱的概念,并重點(diǎn)講解了自動(dòng)裝箱和自動(dòng)拆箱的機(jī)制,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03詳解Java TCC分布式事務(wù)實(shí)現(xiàn)原理
這篇文章主要介紹了詳解Java TCC分布式事務(wù)實(shí)現(xiàn)原理,對(duì)分布式事務(wù)感興趣的同學(xué),一定要看一下2021-04-04Java初學(xué)者入門(mén)之繼承和多態(tài)
Java 面向?qū)ο缶幊逃腥筇匦裕悍庋b、繼承、多態(tài),學(xué)好繼承和多態(tài)是面向?qū)ο箝_(kāi)發(fā)語(yǔ)言中非常重要的一個(gè)環(huán)節(jié),這篇文章主要給大家介紹了關(guān)于Java初學(xué)者入門(mén)之繼承和多態(tài)的相關(guān)資料,需要的朋友可以參考下2021-07-07