SpringBoot WebSocket實現前后端交互 (轉)


原文:https://www.cnblogs.com/xiaozhengtongxue/p/13448778.html

  • websocket: 在瀏覽器和服務器之間建立TCP連接,實現全雙工通信
    springboot使用websocket有兩種方式,一種是實現簡單的websocket,另外一種是實現STOMP協議。本篇講述如何使用springboot實現簡單的websocket。

直接在pom.xml中導入依賴。

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

 

首先注入一個ServerEndpointExporterBean,該Bean會自動注冊使用@ServerEndpoint注解申請的websocket endpoint,代碼如下:

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

 

新建websocket  服務端,在其中處理websocket 邏輯

@Component  //注冊到容器中
//@ServerEndpoint("/webSocket")  //接收websocket請求路徑
@ServerEndpoint("/websocket/{id}")
@Slf4j public class WebSocket { //當前連接(每個websocket連入都會創建一個WebSocket實例) private Session session; //定義一個websocket容器存儲session,即存放所有在線的socket,連接可以改為map private static CopyOnWriteArraySet<WebSocket> webSocketSet = new CopyOnWriteArraySet<>(); //處理連接建立,獲取用戶id @OnOpen public void opOpen(@PathParam(value = "id") String id,Session session){ this.session = session; log.info("【有新的客戶端連接了】:{}",session.getId()); webSocketSet.add(this); //將新用戶加入在線組 log.info("【websocket消息】有新的連接,總數:{}",webSocketSet.size()); } //處理連接關閉 @OnClose public void Onclose(){ webSocketSet.remove(this); log.info("【websocket消息】連接斷開,總數:{}",webSocketSet.size()); } //接受消息 @OnMessage public void onMessage(String message){ log.info("【websocket消息】收到客戶端發來的消息:{}",message); } // 群發消息 public void sendMessage(String message) { for (WebSocket webSocket : webSocketSet) { log.info("【websocket消息】廣播群發消息,message={}",message); try { webSocket.session.getBasicRemote().sendText(message); }catch (Exception e){ e.printStackTrace(); } } } }

客戶可以使用freeMarker模板工具實現。

 

前端實現,建議:https://blog.csdn.net/LiLi_code/article/details/86583347

由於部分瀏覽器可能不支持,可以先測試,代碼如下:

<script>
    var websocket = null;
    if('WebSocket' in window){
        websocket = new WebSocket('ws://localhost:8080/webSocket');
    }else{
        alert('當前瀏覽器不支持websocket消息通知');
    }

    //連接成功建立的回調方法
    websocket.onopen = function (event) {
        console.log("ws建立連接成功");
    }

    //連接關閉的回調方法
    websocket.onclose = function (event) {
        console.log("ws連接關閉");
    }

    //接收到消息的回調方法
    websocket.onmessage = function (event) {
        /*setMessageInnerHTML(event.data);*/
       // alert("ws接收返回消息:"+event.data);
        console.log("服務器返回消息: " + event.data);
        //彈窗提醒(要用到JQuary,所以要先引入JQuary)   播放音樂
        $('#mymodal').modal('show')
    }

    //連接發生錯誤的回調方法
    websocket.onerror = function(event){
        alert('websocket通信發生錯誤!')
    }

    //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。
    window.onbeforeunload = function() {
        websocket.close();
    }
    </script>

測試:(項目實現客戶創建訂單之后,前台發出提醒)

@Autowired
private WebSocket webSocket;

@Override
    @Transactional
    public OrderDTO create(OrderDTO orderDTO) {//創建訂單
        。。。。(具體代碼省略)

       //創建新訂單  發送websocket消息
        webSocket.sendMessage(orderDTO.getOrderId());
        return orderDTO;
    }

 

 

添加新訂單:


接收到websocket消息



 

前端實現,建議:https://blog.csdn.net/LiLi_code/article/details/86583347

index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>聊天室</title>
    </head>
    <body>
    <div id="main">
        <p>
            <input type="text" id="username" placeholder="請輸入用戶名"/>
            <button type="button" id="addBtn">加入</button>
        </p>
        <p>
            <input type="text" id="message" placeholder="請輸入聊天信息"/>
            <button type="button" id="sendBtn" disabled>發送</button>
        </p>
        <ul id="msg"></ul>
    </div>
     
    </body>
    <script>
        window.onload = function () {
            //獲取button對象
            let addBtn = document.getElementById("addBtn")
            let sendBtn = document.getElementById("sendBtn")
            let username = document.getElementById("username")
            var message = document.getElementById("message")
            //定義全局
            let ws = null;
            addBtn.onclick = function () {
                join()
     
            }
     
            //給文本框添加鍵盤點擊事件
            username.onkeyup = function (e) {
                //如果輸入的是回車,進聊天室
                if (e.keyCode === 13) {
                    join()
                    username.disabled = true
                }
            }
     
     
            sendBtn.onclick = function () {
                sendMessage()
            }
            message.onkeyup = function(e){
                if(e.keyCode === 13) sendMessage()
            }
     
            function join() {
                addBtn.disabled = true
                sendBtn.disabled = false
                // 創建WebSocket對象,WebSocket使用的是ws協議
                ws = new WebSocket('ws://localhost:2555')
                ws.onopen = function () {
                    let username = document.getElementById("username").value
                    // 項服務器端發送消息
                    ws.send(
                            // 往后台發送json字符串
                            JSON.stringify({
                                username: username,
                                type: 'login'  //添加的對象
                            })
                    )
                }
                // onmessage與ws已經綁定,接受消息回來的時候還是會回到這里來
                // 服務器發送消息后會觸發
                ws.onmessage = function (e) {
                    console.log(e.data)
                    //字符串對象轉json對象
                    let data = JSON.parse(e.data)
                    let show
                    switch (data.type) {
                        case 'login': //新用戶
                            show = `${data.username}加入了房間`
                            break;
                        case 'msg': // 有新的聊天信息
                            show = `${data.username} ${data.time} <br> ${data.message}`
                            break
                        case 'leave': //有人離開聊天室
                            show = `${data.username}離開了房間 ${data.time}`
                            break;
                    }
                    let li = document.createElement("li")
                    li.innerHTML = show
                    document.getElementById("msg").append(li)
                }
            }
     
            function sendMessage() {
                let username = document.getElementById("username").value
                let msg = document.getElementById("message").value
                //發送聊天消息給服務器
                ws.send(JSON.stringify({
                    username: username,
                    message: msg,
                    type: 'msg'
                }))
                document.getElementById("message").value = ''
            }
        }
    </script>
    </html>

 

app.js

    //后台服務器代碼
    //引入websocket模塊
    let ws = require('nodejs-websocket')
     
    //創建服務對象啟動,監聽端口號是2555
    let server = ws.createServer((conn)=>{
        console.log('有人連接...')
        //當客戶端發消息時會觸發text事件
        conn.on('text',(str)=>{
            let data = JSON.parse(str)
            console.log(data)
            //判斷接受消息的類型
            switch(data.type){
                case 'login': //新用戶加入
                    conn.nickname = data.username //保存用戶名屬性
                    broadcast(
                        //發送json字符串告訴客戶端有新用戶加入
                        JSON.stringify({
                            username:data.username,
                            time:getTime(),
                            type:data.type
                        })
                    )
                    break
                case 'msg':
                    broadcast(
                        JSON.stringify({
                            username:data.username,
                            time:getTime(),
                            message:data.message,
                            type:data.type
                        })
                    )
                    break
            }
        })
     
        //監聽錯誤信息
        conn.on('error',(err)=>{
            console.log(err)
        })
     
        //監聽斷開連接
        conn.on('close',()=>{
            broadcast(
                JSON.stringify({
                    username:conn.nickname,
                    time:getTime(),
                    type:'leave'
                })
            )
        })
     
    }).listen(2555)
     
    //給所有客戶端連接發送消息
    function broadcast(str){
        //遍歷所有的客戶端連接
        server.connections.forEach((conn)=>{
            //發送消息
            conn.send(str)
        })
    }
     
    function getTime(){
        var date = new Date();
        var hour = date.getHours();
        var min = date.getMinutes()
        var sec = date.getSeconds()
        return hour + ":" + min + ":" + sec
    }

不要忘記實現導入websocket框架;

  1. 安裝包 nodejs-websocket
  2. npm install nodejs-websocket

 


免責聲明!

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



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