国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot整合Websocket(Java websocket怎么使用)

這篇具有很好參考價(jià)值的文章主要介紹了SpringBoot整合Websocket(Java websocket怎么使用)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1 Websocket是什么

WebSocket 是一種基于 TCP 協(xié)議的全雙工通信協(xié)議,可以在瀏覽器和服務(wù)器之間建立實(shí)時(shí)、雙向的數(shù)據(jù)通信。可以用于在線聊天、在線游戲、實(shí)時(shí)數(shù)據(jù)展示等場(chǎng)景。與傳統(tǒng)的 HTTP 協(xié)議不同,WebSocket 可以保持長(zhǎng)連接,實(shí)時(shí)傳輸數(shù)據(jù),避免了頻繁的 HTTP 請(qǐng)求和響應(yīng),節(jié)省了網(wǎng)絡(luò)帶寬和服務(wù)器資源,提高了應(yīng)用程序的性能和用戶體驗(yàn)。

2 Websocket可以做什么

項(xiàng)目中大部分的請(qǐng)求都是前臺(tái)主動(dòng)發(fā)送給后臺(tái),后臺(tái)接收后返回?cái)?shù)據(jù)給前臺(tái),返回?cái)?shù)據(jù)后這個(gè)連接就終止了。如果要實(shí)現(xiàn)實(shí)時(shí)通信,通用的方式是采用 HTTP 協(xié)議

不斷發(fā)送請(qǐng)求。但這種方式即浪費(fèi)帶寬(HTTP HEAD 是比較大的),又消耗服務(wù)器 CPU 占用(沒(méi)有信息也要接受請(qǐng)求)。

websocket可以建立長(zhǎng)連接實(shí)現(xiàn)雙向通信,客戶端和服務(wù)端都可以主動(dòng)的向?qū)Ψ桨l(fā)送消息。

例如:

假設(shè)張三今天有個(gè)快遞快到了,但是張三忍耐不住,就每隔十分鐘給快遞員或者快遞站打電話,詢問(wèn)快遞到了沒(méi),每次快遞員就說(shuō)還沒(méi)到,等到下午張三的快遞到了,但是,快遞員不知道哪個(gè)電話是張三的,(可不是只有張三打電話,還有李四,王五),所以只能等張三打電話,才能通知他,你的快遞到了。

而最好的情況是,張三給快遞員第一次打電話時(shí),說(shuō)明自己的身份,快遞員記錄下來(lái),讓自己和快遞員之間形成一對(duì)一的關(guān)系可以互相聯(lián)系到。張三也不用再次給快遞員打電話了,快遞到了快遞員會(huì)主動(dòng)聯(lián)系張三通知他來(lái)取。

后者就是websocket模式,在客戶端斷開(kāi)WebSocket連接或Server端中斷連接前,不需要客戶端和服務(wù)端重新發(fā)起連接請(qǐng)求。在海量并發(fā)及客戶端與服務(wù)器交互負(fù)載流量大的情況下,極大的節(jié)省了網(wǎng)絡(luò)帶寬資源的消耗,有明顯的性能優(yōu)勢(shì),且客戶端發(fā)送和接受消息是在同一個(gè)持久連接上發(fā)起,實(shí)現(xiàn)了“真·長(zhǎng)鏈接”,實(shí)時(shí)性優(yōu)勢(shì)明顯。
SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

在項(xiàng)目中聊天功能也是類似的邏輯,A發(fā)送了消息B立刻就要收到,A和B都屬于前臺(tái)客戶端,不可能直接從一個(gè)前臺(tái)不走服務(wù)器傳輸給另一個(gè)前臺(tái),過(guò)程一定是前臺(tái) —> 服務(wù)器 -> 前臺(tái)。那前臺(tái)客戶端B接收消息是被動(dòng)的,需要服務(wù)器主動(dòng)發(fā)送消息請(qǐng)求,這就用到了WebSocket。大體流程如下圖:
SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

3 Springboot整合Websocket

3.1 服務(wù)端

  1. 添加依賴

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    
  2. 添加Websocket配置文件

    @Configuration
    public class WebSocketConfig {
        /**
         *     注入ServerEndpointExporter,
         *     這個(gè)bean會(huì)自動(dòng)注冊(cè)使用了@ServerEndpoint注解聲明的Websocket
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    
  3. Webscoket操作類

    import org.springframework.stereotype.Component;
    import javax.websocket.*;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.CopyOnWriteArraySet;
    import java.util.logging.Logger;
    import static java.util.logging.Level.WARNING;
    
    @Component
    @ServerEndpoint("/websocket/{userId}")  // 接口路徑 ws://localhost:9001/webSocket/userId;
    public class WebSocket {
    
        private static final Logger log = Logger.getLogger(WebSocket.class.getName());
    
        //與某個(gè)客戶端的連接會(huì)話,需要通過(guò)它來(lái)給客戶端發(fā)送數(shù)據(jù)
        private Session session;
        /**
         * 用戶ID
         */
        private String userId;
    
        //concurrent包的線程安全Set,用來(lái)存放每個(gè)客戶端對(duì)應(yīng)的MyWebSocket對(duì)象。
        //雖然@Component默認(rèn)是單例模式的,但springboot還是會(huì)為每個(gè)websocket連接初始化一個(gè)bean,所以可以用一個(gè)靜態(tài)set保存起來(lái)。
        //  注:底下WebSocket是當(dāng)前類名
        private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
        // 用來(lái)存在線連接用戶信息
        private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();
    
        /**
         * 鏈接成功調(diào)用的方法
         */
        @OnOpen
        public void onOpen(Session session, @PathParam(value="userId")String userId) {
            try {
                this.session = session;
                this.userId = userId;
                webSockets.add(this);
                sessionPool.put(userId, session);
                log.info("【websocket消息】有新的連接,總數(shù)為:"+webSockets.size());
            } catch (Exception e) {
            }
        }
    
        /**
         * 鏈接關(guān)閉調(diào)用的方法
         */
        @OnClose
        public void onClose() {
            try {
                webSockets.remove(this);
                sessionPool.remove(this.userId);
                log.info("【websocket消息】連接斷開(kāi),總數(shù)為:"+webSockets.size());
            } catch (Exception e) {
            }
        }
        /**
         * 收到客戶端消息后調(diào)用的方法
         *
         * @param message
         */
        @OnMessage
        public void onMessage(String message) {
            log.info("【websocket消息】收到客戶端消息:"+message);
        }
    
        /** 發(fā)送錯(cuò)誤時(shí)的處理
         * @param session
         * @param error
         */
        @OnError
        public void onError(Session session, Throwable error) {
    
            log.log(WARNING,"用戶錯(cuò)誤,原因:"+error.getMessage());
            error.printStackTrace();
        }
    
    	/**
    	*	下面為服務(wù)端向客戶端發(fā)送消息
    	*/
        // 此為廣播消息
        public void sendAllMessage(String message) {
            log.info("【websocket消息】廣播消息:"+message);
            for(WebSocket webSocket : webSockets) {
                try {
                    if(webSocket.session.isOpen()) {
                        webSocket.session.getAsyncRemote().sendText(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 此為單點(diǎn)消息
        public void sendOneMessage(String userId, String message) {
            Session session = sessionPool.get(userId);
            if (session != null&&session.isOpen()) {
                try {
                    log.info("【websocket消息】 單點(diǎn)消息:"+message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 此為單點(diǎn)消息(多人)
        public void sendMoreMessage(String[] userIds, String message) {
            for(String userId:userIds) {
                Session session = sessionPool.get(userId);
                if (session != null&&session.isOpen()) {
                    try {
                        log.info("【websocket消息】 單點(diǎn)消息:"+message);
                        session.getAsyncRemote().sendText(message);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    

    上面的操作類中有幾個(gè)主要的點(diǎn)需要注意

    • @ServerEndpoint注解:注解的value屬性為調(diào)用時(shí)路徑。類似于@RequestMapping("")設(shè)置的路徑。添加該注解,才會(huì)被注冊(cè)。
    • @OnOpen:鏈接成功調(diào)用的方法。
    • @OnMessage:客戶端可以主動(dòng)給服務(wù)端發(fā)送消息,此方法接受數(shù)據(jù)并處理。
    • @OnError:發(fā)送錯(cuò)誤時(shí)的處理。
  4. 服務(wù)端主動(dòng)向客戶端發(fā)送消息

    測(cè)試用例

    @Resource
    private WebSocket webSocket;
    
    @GetMapping("sendMessage")
    public AjaxResult queryById(@Validated @NotNull Long id){
        //創(chuàng)建業(yè)務(wù)消息信息
        JSONObject obj = new JSONObject();
        obj.put("msgId", "00000001");//消息id
    	obj.put("msgTxt", "服務(wù)端->客戶端發(fā)送消息");//消息內(nèi)容
        //全體發(fā)送
        webSocket.sendAllMessage(obj.toJSONString());
        //單個(gè)用戶發(fā)送 (userId為用戶id)
        //webSocket.sendOneMessage(userId, obj.toJSONString());
        //多個(gè)用戶發(fā)送 (userIds為多個(gè)用戶id,逗號(hào)‘,’分隔)
        //webSocket.sendMoreMessage(userIds, obj.toJSONString());
        return AjaxResult.success("執(zhí)行成功");
    }
    

3.2 客戶端

<script>
export default {
  name: "index",
  data() {
    return {
      websock:null
    };
  },
  mounted() {
    //初始化websocket
    this.initWebSocket()
  },
  destroyed: function () {
    //關(guān)閉連接
    this.websocketclose();
  },
  methods: {
    initWebSocket: function () { // 建立連接
      // WebSocket與普通的請(qǐng)求所用協(xié)議有所不同,ws等同于http,wss等同于https
      var userId = "user-001";
      var url = "ws://localhost:9001/websocket/" + userId;
      this.websock = new WebSocket(url);
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onclose = this.websocketclose;
    },
    // 連接成功后調(diào)用
    websocketonopen: function () {
      console.log("WebSocket連接成功");
    },
    // 發(fā)生錯(cuò)誤時(shí)調(diào)用
    websocketonerror: function (e) {
      console.log("WebSocket連接發(fā)生錯(cuò)誤");
    },
	// 接收后端消息
    websocketonmessage: function (e) {
      console.log("eee",e)
      var data = eval("(" + e.data + ")"); 
    },
    // 關(guān)閉連接時(shí)調(diào)用
    websocketclose: function (e) {
      console.log("connection closed (" + e.code + ")");
    },
    //向后臺(tái)發(fā)送消息
    sendMessage(){
      let params = {
        id:"00000",
        msg:"前端消息測(cè)試"
      }
      let a = JSON.stringify(params);
      this.websock.send(a)
    },
  }
</script>

websockke中內(nèi)置了連接、錯(cuò)誤、接收消息、接收消息、關(guān)閉的回調(diào),下面自己定義的websocketonopen、websocketonmessage等方法的名字可以隨便起,但需要在初始化時(shí)賦值給websocket對(duì)應(yīng)的屬性。

屬性 事件處理回調(diào)函數(shù) 描述
onopen websocketonopen 建立連接時(shí)觸發(fā)
onerror websocketonerror 通信發(fā)生錯(cuò)誤時(shí)觸發(fā)
onmessage websocketonmessage 客戶端接收服務(wù)端消息時(shí)觸發(fā)
onclose websocketclose 連接關(guān)閉觸發(fā)
send 無(wú) 不需要回調(diào)函數(shù),建議直接調(diào)用websocket的send方法

下面測(cè)試下完整流程

  • 創(chuàng)建連接

    ws同http,wss同https,后面路徑為服務(wù)段@ServerEndpoint注解的值,以此選擇連接不同連接端。
    SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

  • 前臺(tái)客戶端主動(dòng)發(fā)送消息給服務(wù)端

    調(diào)用websock.send()方法,但消息的類型需要注意,socket本質(zhì)是傳輸字節(jié)流,所以不能把任意類型的數(shù)據(jù)直接傳入send方法,限制類型如下:
    SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

    等接收到數(shù)據(jù)以后通過(guò)IO包裝類都可以把數(shù)據(jù)還原。

    服務(wù)端成功接收到消息:
    SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

  • 服務(wù)端主動(dòng)向客戶端發(fā)送消息

    客戶端成功接收
    SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java
    SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java

    可以看到是一個(gè)請(qǐng)求長(zhǎng)連接:

    • 綠色向上的箭頭是客戶端發(fā)送給服務(wù)端
    • 紅色向下的箭頭是服務(wù)端發(fā)送給客戶端

上述測(cè)試的流程如下:
SpringBoot整合Websocket(Java websocket怎么使用),Java,websocket,網(wǎng)絡(luò)協(xié)議,springboot,java文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-691389.html

到了這里,關(guān)于SpringBoot整合Websocket(Java websocket怎么使用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Springboot 整合 WebSocket ,使用STOMP協(xié)議+Redis 解決負(fù)載場(chǎng)景問(wèn)題

    Springboot 整合 WebSocket ,使用STOMP協(xié)議+Redis 解決負(fù)載場(chǎng)景問(wèn)題

    ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jacksonSeial.setObjectMapper(om); template.setValueSerializer(jacksonSeial); template.setKeySerializer(stringRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); template

    2024年04月14日
    瀏覽(48)
  • 【W(wǎng)ebSocket】SpringBoot整合WebSocket實(shí)現(xiàn)聊天室(一)

    【W(wǎng)ebSocket】SpringBoot整合WebSocket實(shí)現(xiàn)聊天室(一)

    目錄 一、準(zhǔn)備 1、引入依賴 2、創(chuàng)建配置類 二、相關(guān)注解 首先我們需要在項(xiàng)目中引入依賴,有兩種方式。第一種我們可以在創(chuàng)建Spring Boot項(xiàng)目時(shí)搜索WebSocket然后勾選依賴 第二種是我們可以直接在項(xiàng)目的pom.xml文件中插入以下依賴 我們需要進(jìn)行如下配置 ServerEndpointExporter 是一個(gè)

    2024年02月13日
    瀏覽(91)
  • springboot整合websocket教程

    Websocket是一種網(wǎng)絡(luò)協(xié)議,它允許瀏覽器和服務(wù)器之間進(jìn)行實(shí)時(shí)雙向數(shù)據(jù)傳輸。 在本教程中,我們將創(chuàng)建一個(gè)簡(jiǎn)單的聊天應(yīng)用程序,使用Websocket實(shí)現(xiàn)實(shí)時(shí)通信。 添加依賴 我們需要添加Spring Boot Websocket依賴,以便我們可以使用Spring Boot中提供的Websocket支持。 配置WebSocket 在Sprin

    2023年04月23日
    瀏覽(18)
  • WebSocket--整合springboot

    目錄 握手?jǐn)r截器 WebSocket處理程序 HttpSessionHandshakelnterceptor (抽象類):? ?握手?jǐn)r截器,在握手前后添加操作 AbstractWebSocketHandler (抽象類) :? ?WebSocket處理程序,監(jiān)聽(tīng)連接前,連接中,連接后WebSocketConfigurer (接口):? ? 配置程序,比如配置監(jiān)聽(tīng)哪個(gè)端口,上面的握手?jǐn)r截器,處理

    2024年01月16日
    瀏覽(29)
  • 教你怎么使用Java實(shí)現(xiàn)WebSocket

    教你怎么使用Java實(shí)現(xiàn)WebSocket

    一、WebSocket簡(jiǎn)介 WebSocket協(xié)議通過(guò)在客戶端和服務(wù)端之間提供全雙工通信來(lái)進(jìn)行Web和服務(wù)器的交互功能。 在WebSocket應(yīng)用程序中,服務(wù)器發(fā)布WebSocket端點(diǎn),客戶端使用url連接到服務(wù)器。建立連接后,服務(wù)器和客戶端就可以互相發(fā)送消息??蛻舳送ǔ_B接到一臺(tái)服務(wù)器,服務(wù)器接

    2024年01月17日
    瀏覽(19)
  • [超詳細(xì)]SpringBoot整合WebSocket

    WebSocket 是一種在單個(gè) TCP 連接上進(jìn)行全雙工通信的協(xié)議,它允許在瀏覽器和服務(wù)器之間進(jìn)行實(shí)時(shí)的、雙向的通信。相對(duì)于傳統(tǒng)的基于請(qǐng)求和響應(yīng)的 HTTP 協(xié)議,WebSocket 提供了一種更有效、更實(shí)時(shí)的通信方式,適用于需要實(shí)時(shí)更新、實(shí)時(shí)通知和實(shí)時(shí)交互的應(yīng)用。 WebSocket 的一些關(guān)

    2024年02月11日
    瀏覽(19)
  • SpringBoot整合WebSocket詳細(xì)教程

    SpringBoot整合WebSocket詳細(xì)教程

    共開(kāi)啟兩個(gè)頁(yè)面,實(shí)現(xiàn)一對(duì)一聊天。 服務(wù)端代碼:https://gitee.com/lianaozhe/springboot-websocket.git 導(dǎo)入相關(guān)依賴: WebSocketConfig配置類: WebSocket操作類: TestController測(cè)試接口類: test.html文件: 復(fù)制test.html文件為test2.html文件,將上面的userId由’20’改為’10’,后面測(cè)試使用。 運(yùn)行服

    2024年02月01日
    瀏覽(20)
  • WebSocket整合springboot顯示進(jìn)度條

    WebSocket整合springboot顯示進(jìn)度條

    SpringBoot整合WebScoket顯示進(jìn)度條 - 鐘小嘿 - 博客園 對(duì)于大文件上傳解析,若直接上傳,會(huì)超時(shí),可使用WebSocket長(zhǎng)鏈接方式實(shí)時(shí)顯示文件的上傳狀態(tài),實(shí)際上是從文件上傳到內(nèi)容解析完成存入數(shù)據(jù)庫(kù)的過(guò)程,各個(gè)階段的進(jìn)度可自定義。 本文使用SpringBoot+WebSocket+vue2.0+Element+nginx實(shí)

    2024年02月14日
    瀏覽(20)
  • springboot整合websocket(詳解、教程、代碼)

    springboot整合websocket(詳解、教程、代碼)

    大家好,我是酷酷的韓~ 1.websocket定義 WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工(full-duplex)通信——允許服務(wù)器主動(dòng)發(fā)送信息給客戶端。websocket 協(xié)議是在 http 協(xié)議上的一種補(bǔ)充協(xié)議,是 html5 的新特性,是一種持久化的協(xié)議。 2.websocket工作原理

    2024年02月02日
    瀏覽(21)
  • 【十六】springboot整合WebSocket(超詳細(xì))

    【十六】springboot整合WebSocket(超詳細(xì))

    ?springboot篇章整體欄目:? 【一】springboot整合swagger(超詳細(xì) 【二】springboot整合swagger(自定義)(超詳細(xì)) 【三】springboot整合token(超詳細(xì)) 【四】springboot整合mybatis-plus(超詳細(xì))(上) 【五】springboot整合mybatis-plus(超詳細(xì))(下) 【六】springboot整合自定義全局異常處

    2023年04月09日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包