欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用spring?boot+WebSocket實(shí)現(xiàn)后臺(tái)主動(dòng)消息推送功能

 更新時(shí)間:2022年04月29日 09:29:21   作者:迷途小羔羊678  
目前對(duì)于服務(wù)端向客戶端推送數(shù)據(jù),常用技術(shù)方案有輪詢、websocket等,下面這篇文章主要給大家介紹了關(guān)于利用spring?boot+WebSocket實(shí)現(xiàn)后臺(tái)主動(dòng)消息推送功能的相關(guān)資料,需要的朋友可以參考下

前言:

使用此webscoket務(wù)必確保生產(chǎn)環(huán)境能兼容/支持!使用此webscoket務(wù)必確保生產(chǎn)環(huán)境能兼容/支持!使用此webscoket務(wù)必確保生產(chǎn)環(huán)境能兼容/支持!主要是tomcat的兼容與支持。

有個(gè)需求:

APP用戶產(chǎn)生某個(gè)操作,需要讓后臺(tái)管理系統(tǒng)部分人員感知(表現(xiàn)為一個(gè)頁(yè)面消息)。

最早版本是后臺(tái)管理系統(tǒng)輪訓(xùn),每隔一段時(shí)間輪訓(xùn)一次,由于消息重要,每隔幾秒就查一次。這樣做明顯很不雅!會(huì)消耗大量資源,并且大部分請(qǐng)求是沒(méi)有用的(查不到數(shù)據(jù)進(jìn)來(lái)),很藍(lán)瘦。

后來(lái),想著用消息推送的方式來(lái)處理這個(gè)邏輯。用戶在app產(chǎn)生了目標(biāo)操作,即產(chǎn)生一個(gè)消息,推送給后臺(tái)管理系統(tǒng)的對(duì)應(yīng)用戶。

然后我就找各種資料,一開(kāi)始同事推薦dwz,后來(lái)發(fā)現(xiàn)不太適用于目前的項(xiàng)目(也許能實(shí)現(xiàn)只是我不知道如何實(shí)現(xiàn))。

后來(lái)了解到WebSocket,網(wǎng)上看了很多文檔都是類似聊天室的場(chǎng)景,有些不同。在此,我主要側(cè)重介紹下 服務(wù)器主動(dòng)推送,由服務(wù)端來(lái)觸發(fā)。

WebSocket 主要能實(shí)現(xiàn)的場(chǎng)景:

1、網(wǎng)頁(yè)聊天室

2、服務(wù)器消息實(shí)時(shí)通知

WebSocket 使用方法應(yīng)該有很多,在次介紹下使用  tomcat8+h5 環(huán)境下的實(shí)現(xiàn)。

ps:我自己的測(cè)試環(huán)境是tomcat7這樣寫(xiě)是不行的。wang115032337《https://blog.csdn.net/wang115032337》這位朋友在他的環(huán)境下,tomcat7/8都可以用本文章的寫(xiě)法,只不過(guò)需要去除WebSocketConfig類(有文章表示tomcat7和8對(duì)websocket的支持是不同的,本人未深入了解)

話不多說(shuō),直接上代碼,想深入了解WebSocket 的請(qǐng)查閱相關(guān)介紹。

1.pom

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

2. 使用@ServerEndpoint創(chuàng)立websocket endpoint( wang115032337這位朋友在他的環(huán)境下加入@ServerEndpoint類會(huì)報(bào)錯(cuò),直接刪除了仍可用)

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

3.具體實(shí)現(xiàn)類 可自己選擇url要不要帶參數(shù)

package com.star.manager.service;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
//@ServerEndpoint("/websocket/{user}")
@ServerEndpoint(value = "/websocket")
@Component
public class WebSocketServer {
    //靜態(tài)變量,用來(lái)記錄當(dāng)前在線連接數(shù)。應(yīng)該把它設(shè)計(jì)成線程安全的。
    private static int onlineCount = 0;
    //concurrent包的線程安全Set,用來(lái)存放每個(gè)客戶端對(duì)應(yīng)的MyWebSocket對(duì)象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
    //與某個(gè)客戶端的連接會(huì)話,需要通過(guò)它來(lái)給客戶端發(fā)送數(shù)據(jù)
    private Session session;
    /**
     * 連接建立成功調(diào)用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在線數(shù)加1
        log.info("有新連接加入!當(dāng)前在線人數(shù)為" + getOnlineCount());
        try {
             sendMessage("連接成功");
        } catch (IOException e) {
            log.error("websocket IO異常");
        }
    }
    //    //連接打開(kāi)時(shí)執(zhí)行
    //    @OnOpen
    //    public void onOpen(@PathParam("user") String user, Session session) {
    //        currentUser = user;
    //        System.out.println("Connected ... " + session.getId());
    //    }
 
    /**
     * 連接關(guān)閉調(diào)用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //從set中刪除
        subOnlineCount();           //在線數(shù)減1
        log.info("有一連接關(guān)閉!當(dāng)前在線人數(shù)為" + getOnlineCount());
    }
 
    /**
     * 收到客戶端消息后調(diào)用的方法
     *
     * @param message 客戶端發(fā)送過(guò)來(lái)的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("來(lái)自客戶端的消息:" + message);
 
        //群發(fā)消息
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    /**
     * 
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("發(fā)生錯(cuò)誤");
        error.printStackTrace();
    }
 
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
 
    /**
     * 群發(fā)自定義消息
     * */
    public static void sendInfo(String message) throws IOException {
        log.info(message);
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }
 
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
 
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
 
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
}

產(chǎn)生一個(gè)消息:產(chǎn)生消息場(chǎng)景有多種,http(s),定時(shí)任務(wù),mq等,這貼一個(gè)httpq請(qǐng)求的controller代碼

     @RequestMapping(value="/pushVideoListToWeb",method=RequestMethod.POST,consumes = "application/json")
     public @ResponseBody Map<String,Object> pushVideoListToWeb(@RequestBody Map<String,Object> param) {
         Map<String,Object> result =new HashMap<String,Object>();
         try {
             WebSocketServer.sendInfo("有新客戶呼入,sltAccountId:"+CommonUtils.getValue(param, "sltAccountId"));
             result.put("operationResult", true);
         }catch (IOException e) {
             result.put("operationResult", true);
         }
         return result;
     }

重要的地方我都加粗了,主要是這段,使用這個(gè)方法,可以實(shí)現(xiàn)服務(wù)器主動(dòng)推送。

    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

4.js(html就不寫(xiě)了,隨便找個(gè)能觸發(fā)這個(gè)js的就可以)

//socket = new WebSocket("ws://localhost:9094/starManager/websocket/張三");
        var socket;
        if(typeof(WebSocket) == "undefined") {
            console.log("您的瀏覽器不支持WebSocket");
        }else{
            console.log("您的瀏覽器支持WebSocket");
            
            //實(shí)現(xiàn)化WebSocket對(duì)象,指定要連接的服務(wù)器地址與端口  建立連接
            //socket = new WebSocket("ws://localhost:9094/starManager/websocket/張三")
            socket = new WebSocket("ws://localhost:9094/starManager/websocket");
            //打開(kāi)事件
            socket.onopen = function() {
                console.log("Socket 已打開(kāi)");
                //socket.send("這是來(lái)自客戶端的消息" + location.href + new Date());
            };
            //獲得消息事件
            socket.onmessage = function(msg) {
                console.log(msg.data);
                //發(fā)現(xiàn)消息進(jìn)入    調(diào)后臺(tái)獲取
                getCallingList();
            };
            //關(guān)閉事件
            socket.onclose = function() {
                console.log("Socket已關(guān)閉");
            };
            //發(fā)生了錯(cuò)誤事件
            socket.onerror = function() {
                alert("Socket發(fā)生了錯(cuò)誤");
            }
             $(window).unload(function(){
                  socket.close();
                });
 
//                                    $("#btnSend").click(function() {
//                                        socket.send("這是來(lái)自客戶端的消息" + location.href + new Date());
//                                    });
//
//                                    $("#btnClose").click(function() {
//                                        socket.close();
//                                    });
        }

簡(jiǎn)單說(shuō)說(shuō):

通過(guò)前端代碼 

socket = new WebSocket("ws://localhost:9094/starManager/websocket");

其中,starManager是工程名,/webscoket是訪問(wèn)路徑名

建立連接,前端調(diào)用scoket.open() 會(huì)使后臺(tái)在靜態(tài)成員變量webSocketSet里面增加一個(gè)元素,相當(dāng)于一個(gè)緩存。后臺(tái)服務(wù)調(diào)用sendMessage

(指定某個(gè)用戶,定向)或sendInfo(遍歷webSocketSet逐個(gè)發(fā)送,類似群發(fā))方法,即可向已登錄的客戶端推送消息。

代碼就這么多。我的用這些代碼就跑的起來(lái)。做的時(shí)候出現(xiàn)過(guò)頁(yè)面報(bào)404等錯(cuò)誤,如果也是spring boot+h5,仔細(xì)核對(duì)下和我代碼有無(wú)區(qū)別,加配置 路徑是有ok,問(wèn)題應(yīng)該不大。

如果你恰好也有可以用WebSocket實(shí)現(xiàn)的類似場(chǎng)景,希望對(duì)你有幫助。

總結(jié)

到此這篇關(guān)于利用spring boot+WebSocket實(shí)現(xiàn)后臺(tái)主動(dòng)消息推送功能的文章就介紹到這了,更多相關(guān)springboot+WebSocket消息推送內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論