最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot整合WebSocket實(shí)戰(zhàn)教程

 更新時間:2023年05月26日 09:18:28   作者:山河亦問安  
WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動向客戶端推送數(shù)據(jù),這篇文章主要介紹了Springboot整合WebSocket實(shí)戰(zhàn)教程,需要的朋友可以參考下

1.WebSocket 簡介

WebSocket是一種在單個TCP連接上進(jìn)行全雙工通信的協(xié)議。WebSocket使得客戶端和服務(wù)器之間的數(shù)據(jù)交換變得更加簡單,允許服務(wù)端主動向客戶端推送數(shù)據(jù)。在WebSocket API中,瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進(jìn)行雙向數(shù)據(jù)傳輸。

bbefc8c835344d69939d06856acdb9cd.png

 WebSocket特點(diǎn):
1.建立在 TCP 協(xié)議之上,服務(wù)器端的實(shí)現(xiàn)比較容易。
2.與 HTTP 協(xié)議有著良好的兼容性。默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議,因此3.握手時不容易屏蔽,能通過各種HTTP 代理服務(wù)器。
4.數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
5.可以發(fā)送文本,也可以發(fā)送二進(jìn)制數(shù)據(jù)。
6.沒有同源限制,客戶端可以與任意服務(wù)器通信。
7.協(xié)議標(biāo)識符是ws(如果加密,則為wss),服務(wù)器網(wǎng)址就是 URL。

HTTP缺點(diǎn):通過反復(fù)的輪訓(xùn)去查看資源是否有更新,對網(wǎng)絡(luò)和資源有很大的消耗
websocket可以反向通知,雙向通訊

2.WebSocket 實(shí)戰(zhàn)

導(dǎo)入依賴

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

配置類

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

WebSocketServer類

@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocketServer {
    /**
     * 日志工具
     */
    protected static final Logger logger= LoggerFactory.getLogger(WebSocketServer.class);
    /**
     * 與某個客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)
     */
    private Session session;
    /**
     * 用戶id
     */
    private String userId;
    /**
     * 用來存放每個客戶端對應(yīng)的MyWebSocket對象
     */
    private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
    /**
     * 用來存在線連接用戶信息
     */
    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);
            logger.info("有新的客戶連接,總數(shù)為:" + webSockets.size());
        } catch (Exception e) {
        }
    }
    /**
     * 鏈接關(guān)閉調(diào)用的方法
     */
    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            sessionPool.remove(this.userId);
            logger.info("【websocket消息】連接斷開,總數(shù)為:" + webSockets.size());
        } catch (Exception e) {
        }
    }
    /**
     * 收到客戶端消息后調(diào)用的方法
     */
    @OnMessage
    public void onMessage(String message) {
        logger.info("【websocket消息】收到客戶端消息:" + message);
    }
    /**
     * 發(fā)送錯誤時的處理
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("用戶錯誤,原因:" + error.getMessage());
        error.printStackTrace();
    }
    /**
     * 此為廣播消息
     */
    public void sendAllMessage(String message) {
        logger.info("【websocket消息】廣播消息:" + message);
        for (WebSocketServer 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 {
                logger.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 {
                    logger.info("【websocket消息】 單點(diǎn)消息:" + message);
                    session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

服務(wù)端發(fā)送消息實(shí)例

    @GetMapping("/hello")
    public void hello(){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("key","hello");
        webSocketServer.sendAllMessage(JSONObject.toJSONString(jsonObject));
    }

客戶端

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" rel="external nofollow"  />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + Vue</title>
  </head>
  <body>
  <p>【socket開啟者的ID信息】:<div><input id="userId" name="userId" type="text" value="10"></div>
    <div><input id="contentText" name="contentText" type="text" value="hello websocket"></div>
  <p>【操作】:<button><a onclick="openSocket()">發(fā)送消息</a></button>
  </body>
  <script>
    let socket;
    function openSocket() {
      const socketUrl = "ws://localhost:8080/websocket/"+$("#userId").val();
      socket = new WebSocket(socketUrl);
      //打開事件
      socket.onopen = function() {
        console.log("websocket已打開");
        socket.send('{"toUserId":"'+$("#userId").val()+'","contentText":"'+$("#contentText").val()+'"}');
        console.log('{"toUserId":"'+$("#userId").val()+'","contentText":"'+$("#contentText").val()+'"}');
      };
      //獲得消息事件
      socket.onmessage = function(msg) {
        console.log(msg.data);
        //發(fā)現(xiàn)消息進(jìn)入,開始處理前端觸發(fā)邏輯
      };
      //關(guān)閉事件
      socket.onclose = function() {
        console.log("websocket已關(guān)閉");
      };
      //發(fā)生了錯誤事件
      socket.onerror = function() {
        console.log("websocket發(fā)生了錯誤");
      }
    }
  </script>
</html>

到此這篇關(guān)于Springboot整合WebSocket實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)Springboot整合WebSocket內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解析spring-boot-starter-parent簡介

    解析spring-boot-starter-parent簡介

    本文通過代碼的形式給大家介紹了spring-boot-starter-parent的基礎(chǔ)知識,需要的朋友可以參考下
    2018-09-09
  • 使用Logback設(shè)置property參數(shù)方式

    使用Logback設(shè)置property參數(shù)方式

    這篇文章主要介紹了使用Logback設(shè)置property參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java獲取線程ID的實(shí)例

    Java獲取線程ID的實(shí)例

    以下實(shí)例演示了如何使用 getThreadId() 方法獲取線程id,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-10-10
  • 基于jvm java內(nèi)存區(qū)域的介紹

    基于jvm java內(nèi)存區(qū)域的介紹

    下面小編就為大家?guī)硪黄趈vm java內(nèi)存區(qū)域的介紹。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 了解JAVA Future類

    了解JAVA Future類

    Future是并發(fā)編程中的一種設(shè)計模式,F(xiàn)uture它代表一個異步計算的結(jié)果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面小編和大家來一起學(xué)習(xí)一下吧
    2019-06-06
  • Java Process詳解及實(shí)例

    Java Process詳解及實(shí)例

    這篇文章主要介紹了Java Process詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • JDBC連接MySQL數(shù)據(jù)庫批量插入數(shù)據(jù)過程詳解

    JDBC連接MySQL數(shù)據(jù)庫批量插入數(shù)據(jù)過程詳解

    這篇文章主要介紹了JDBC連接MySQL數(shù)據(jù)庫批量插入數(shù)據(jù)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • springboot中請求地址轉(zhuǎn)發(fā)的兩種方案

    springboot中請求地址轉(zhuǎn)發(fā)的兩種方案

    在開發(fā)過程中,我們經(jīng)常需要將請求從一個服務(wù)轉(zhuǎn)發(fā)到另一個服務(wù),以實(shí)現(xiàn)不同服務(wù)之間的協(xié)作,本文主要介紹了springboot中請求地址轉(zhuǎn)發(fā)的兩種方案,感興趣的可以了解一下
    2023-11-11
  • 線程池滿Thread?pool?exhausted排查和解決方案

    線程池滿Thread?pool?exhausted排查和解決方案

    這篇文章主要介紹了線程池滿Thread?pool?exhausted排查和解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Spring?AOP中三種增強(qiáng)方式的示例詳解

    Spring?AOP中三種增強(qiáng)方式的示例詳解

    AOP?(Aspect?Orient?Programming),直譯過來就是?面向切面編程。AOP?是一種編程思想,是面向?qū)ο缶幊蹋∣OP)的一種補(bǔ)充。本文為大家介紹了Spring?AOP中三種增強(qiáng)方式,感興趣的可以了解一下
    2022-07-07

最新評論

商丘市| 洛隆县| 扎兰屯市| 安陆市| 顺义区| 五原县| 西丰县| 资阳市| 潼关县| 湟源县| 高阳县| 胶州市| 平阳县| 西丰县| 玛沁县| 潼关县| 永定县| 诸暨市| 吉林省| 拜城县| 呈贡县| 罗定市| 建德市| 尚志市| 高台县| 浦县| 宝应县| 宜阳县| 门头沟区| 古交市| 冷水江市| 浦江县| 陕西省| 南宁市| 元氏县| 简阳市| 乌审旗| 昭平县| 湟源县| 讷河市| 珠海市|