SpringBoot整合WebSocket


WebSocket協議是一種全雙工協議,服務端可以主動向客戶端推送消息,可以是文本也可以是二進制數據,而且沒有同源策略的限制,不存在跨域問題。這里主要介紹服務端向客戶端推送消息。

第一步:導入依賴

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>

第二步:創建WebSocket進行消息的推送

package com.example.websocket.controller;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author: yushizhong
 * @Date: 2020/1/10 15:42
 * @Title: 描述
 */
@Component
@ServerEndpoint(value = "/ws/myWebSocket")
public class WebSocket {

    //每個客戶端都會有相應的session,服務端可以發送相關消息
    private Session session;

    //J.U.C包下線程安全的類,主要用來存放每個客戶端對應的webSocket連接,為什么說他線程安全。在文末做簡單介紹
    private static CopyOnWriteArraySet<WebSocket> copyOnWriteArraySet = new CopyOnWriteArraySet<WebSocket>();

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

    /**
     * 打開連接。進入頁面后會自動發請求到此進行連接
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        copyOnWriteArraySet.add(this);
        System.out.println("websocket有新的連接, 總數:"+ copyOnWriteArraySet.size());

    }

    /**
     * 用戶關閉頁面,即關閉連接
     */
    @OnClose
    public void onClose() {
        copyOnWriteArraySet.remove(this);
        System.out.println("websocket連接斷開, 總數:"+ copyOnWriteArraySet.size());
    }

    /**
     * 測試客戶端發送消息,測試是否聯通
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        System.out.println("websocket收到客戶端發來的消息:"+message);
        sendMessage(message);
    }


    /**
     * 出現錯誤
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("發生錯誤:" + error.getMessage()+session.getId());
        error.printStackTrace();
    }

    /**
     * 用於發送給客戶端消息(群發)
     * @param message
     */

    public void sendMessage(String message) {


        //遍歷客戶端
        for (WebSocket webSocket : copyOnWriteArraySet) {
            System.out.println("websocket廣播消息:" + message);
            try {
                //服務器主動推送
                webSocket.session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 用於發送給指定客戶端消息,
     *
     * @param message
     */
    public void sendMessage(String sessionId, String message) throws IOException {
        Session session = null;
        WebSocket tempWebSocket = null;
        for (WebSocket webSocket : copyOnWriteArraySet) {
            if (webSocket.session.getId().equals(sessionId)) {
                tempWebSocket = webSocket;
                session = webSocket.session;
                break;
            }
        }
        if (session != null) {
            tempWebSocket.session.getBasicRemote().sendText(message);
        } else {
            System.out.println("沒有找到你指定ID的會話:{}"+sessionId);
        }
    }




}

第三步:創建頁面chat.html,導入相關的js文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocket</title>
    <script src="stomp.min.js"></script>
    <script src="sockjs.min.js"></script>
</head>
<body>
    <h2>測試連接websocket</h2>
    <p>
        連接url:
        <input type="text" value="ws://localhost:8080/ws/myWebSocket" id="url">
        <button onclick="openWeb()">打開連接</button>
    </p>
    <p>
        發送信息內容:
        <input type="text" id="message"><button onclick="send()">發送信息</button>
    </p>
    <hr>
    <p>消息區域</p>
    <p id="show"></p>

</body>
<script type="text/javascript">
    var url="";//socket所需要的地址
    var socket;//socket對象
    function openWeb(){
        createWebSocket(document.getElementById("url").value)
    }

    //創建WebSocket連接
    function createWebSocket(url){
        if ('WebSocket' in window) {
            socket = new WebSocket(url);
        } else {
            socket = new SockJS(url);
        }

        //連接打開事件
        socket.onopen = function() {
            console.log("Socket已連接到"+url);
        };

        //收到服務器消息后響應
        socket.onmessage = function(e) {
            console.log("收到服務端消息:"+e.data)
            document.getElementById("show").innerHTML+="<br>"+e.data
        };

        //連接關閉事件
        socket.onclose = function() {
            console.log("Socket已關閉連接");
        };
        //發生了錯誤事件
        socket.onerror = function() {
            console.log("Socket發生了錯誤");
        }

        //窗口關閉時,關閉連接
        window.unload=function() {
            socket.close();
        };

    }

    function send(){
        socket.send(document.getElementById("message").value)
    }

</script>

</html>

第四步:測試。啟動項目,在瀏覽器輸入localhost:8080/chat.html,然后點擊連接wensocket進行連接,接着輸入要發送的信息,點擊發送就可以在下面看到發送的信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM