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

Springboot整合WebSocket實(shí)現(xiàn)主動(dòng)向前端推送消息

這篇具有很好參考價(jià)值的文章主要介紹了Springboot整合WebSocket實(shí)現(xiàn)主動(dòng)向前端推送消息。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

? ? ? ? 在上篇文章tcp編程中,我們實(shí)現(xiàn)了C++客戶端與java服務(wù)器之間的通信,客戶端發(fā)送了一個(gè)消息給服務(wù)器,今天我們要實(shí)現(xiàn)基于WebSocket實(shí)現(xiàn)服務(wù)器主動(dòng)向前端推送消息,并且以服務(wù)器接收到C++客戶端的消息主動(dòng)向前端推送消息的觸發(fā)條件。

了解Websocket

WebSocket 的誕生背景

????????在早期,網(wǎng)站為了實(shí)現(xiàn)推送技術(shù),通常使用輪詢(或稱(chēng)為短輪詢)。輪詢是指瀏覽器每隔一段時(shí)間向服務(wù)器發(fā)出 HTTP 請(qǐng)求,然后服務(wù)器返回最新的數(shù)據(jù)給客戶端。這種方式存在明顯的缺點(diǎn):瀏覽器需要不斷地向服務(wù)器發(fā)出請(qǐng)求,而每次請(qǐng)求都包含較長(zhǎng)的頭部信息,導(dǎo)致帶寬資源浪費(fèi)。

????????為了解決這個(gè)問(wèn)題,HTML5?定義了?WebSocket 協(xié)議,它能更好地節(jié)省服務(wù)器資源和帶寬,并且能夠更實(shí)時(shí)地進(jìn)行通訊。

WebSocket 的基本原理

  1. WebSocket 是什么?

  • WebSocket 是一種網(wǎng)絡(luò)傳輸協(xié)議,基于?TCP?實(shí)現(xiàn)。
  • 它在單個(gè) TCP 連接上進(jìn)行全雙工通信,位于 OSI 模型的應(yīng)用層。
  • 與 HTTP 不同,WebSocket 需要先創(chuàng)建連接,然后可以進(jìn)行雙向數(shù)據(jù)傳輸。
  1. WebSocket 握手過(guò)程

  • 客戶端通過(guò) WebSocket 構(gòu)造函數(shù)創(chuàng)建 WebSocket 對(duì)象,連接到服務(wù)器的 WebSocket URL。
  • 客戶端發(fā)送類(lèi)似于 HTTP 請(qǐng)求的報(bào)文,服務(wù)器返回接受 WebSocket 協(xié)議的響應(yīng)。
  • 握手成功后,客戶端和服務(wù)器之間的 WebSocket 連接建立,后續(xù)數(shù)據(jù)以幀序列的形式傳輸。

WebSocket 與 HTTP 的區(qū)別

  • WebSocket 使用類(lèi)似于 HTTP 的握手連接,但數(shù)據(jù)傳輸更高效。
  • 較少的控制開(kāi)銷(xiāo):頭部信息較小。
  • 更強(qiáng)的實(shí)時(shí)性:實(shí)時(shí)通信,避免等待請(qǐng)求響應(yīng)。
  • 保持連接狀態(tài):WebSocket 是全雙工通信,不需要反復(fù)發(fā)出請(qǐng)求。無(wú)需重新發(fā)起連接。
  • 更好的二進(jìn)制支持:處理二進(jìn)制內(nèi)容。
  • 可以支持?jǐn)U展:自定義子協(xié)議。

?WebSocket可以做什么

  • 推文
  • 廣告
  • 聊天室
  • 公告消息

????...................?

服務(wù)器端

打開(kāi)idea,創(chuàng)建一個(gè)Springboot項(xiàng)目,添加WebSocket依賴

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

創(chuàng)建一個(gè)WebSocket控制類(lèi),代碼如下

/**
 * WebSocket操作類(lèi)
 */
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")  // 接口路徑 ws://localhost:8081/webSocket/userId;
public class WebSocket {

    /**
     * 與某個(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)前類(lèi)名
     */
    private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
    /**
     * 用來(lái)存所有在線連接用戶信息,用來(lái)存每個(gè)session
      */
    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.error("用戶錯(cuò)誤,原因:"+error.getMessage());
        error.printStackTrace();
    }


    /**
     * 廣播消息
      */
    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();
            }
        }
    }

    /**
     * 向多人發(fā)消息
     */
    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è)和上篇文章一樣的ServerThread類(lèi),添加@Component注解并添加WebSocket的調(diào)用代碼

@Component//注冊(cè)為Springboot管理的bean,否則不能使用Springboot的其它bean
public class faceServerThread implements Runnable{
    @Autowired
    private studentDao dao;//用于訪問(wèn)數(shù)據(jù)庫(kù)
    WebSocket webSocket=new WebSocket();//用于使用WebSocket中的方法
    @Override
    public void run() {
        try {
            ServerSocket server=new ServerSocket(8888);
            Socket socket;
            byte[] buffer = new byte[1024];
            int len;
            student stu;
            while(true)
            {
                socket=server.accept();//處于阻塞狀態(tài),直到客戶端連接
                System.out.println("客戶端連接成功");
                InputStream input=socket.getInputStream();//用于讀取客戶端發(fā)來(lái)的字節(jié)流
                while ((len=input.read(buffer))!=-1){
                    String str = new String(buffer, 0, len);
                    //此處為代碼修改部分
                    stu=dao.selectById(str);
                    if(stu!=null){
                        System.out.println(str);
                        webSocket.sendOneMessage("0",str);
                    }
                    ///
                }
                System.out.println("接收消息完畢");
                //System.out.println("收到消息:"+id);
            }
        } catch (IOException e) {
            System.out.println("客戶端連接失敗:");
            e.printStackTrace();
        }
    }
}

此處實(shí)現(xiàn)了runnable接口,是為了另外開(kāi)一條線程,不與Springboot沖突。?

在啟動(dòng)類(lèi)中添加啟動(dòng)線程

@SpringBootApplication
public class FreshmandemoApplication {
	public static void main(String[] args){
        ConfigurableApplicationContext context=SpringApplication.run(FreshmandemoApplication.class, args);
        faceServerThread faceThread=context.getBean(faceServerThread.class);
        new Thread(faceThread).start();
    }
}

前端客戶端?

添加一個(gè)HTML文件,實(shí)現(xiàn)WebSocket

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
</body>
<script type="text/javascript">
    var socket;
    if (typeof (WebSocket) == "undefined") {
        console.log("您的瀏覽器不支持WebSocket");
    } else {
        console.log("您的瀏覽器支持WebSocket");
        //實(shí)現(xiàn)化WebSocket對(duì)象,指定要連接的服務(wù)器地址與端口  建立連接
        var reqUrl = "http://localhost:8081/websocket/0" ;
        socket = new WebSocket(reqUrl.replace("http", "ws"));
        //打開(kāi)事件
        socket.onopen = function () {
            console.log("Socket 已打開(kāi)");
            //socket.send("這是來(lái)自客戶端的消息" + location.href + new Date());
        };
        //獲得消息事件
        socket.onmessage = function (msg) {
            console.log("onmessage--" + msg.data);
            //發(fā)現(xiàn)消息進(jìn)入    開(kāi)始處理前端觸發(fā)邏輯
        };
        //關(guān)閉事件
        socket.onclose = function () {
            console.log("Socket已關(guān)閉");
        };
        //發(fā)生了錯(cuò)誤事件
        socket.onerror = function () {
            alert("Socket發(fā)生了錯(cuò)誤");
            //此時(shí)可以嘗試刷新頁(yè)面
        }
        //離開(kāi)頁(yè)面時(shí),關(guān)閉socket
        //jquery1.8中已經(jīng)被廢棄,3.0中已經(jīng)移除
        // $(window).unload(function(){
        //     socket.close();
        //});
    }

  /*  function sendMessage() {
        if (typeof (WebSocket) == "undefined") {
            console.log("您的瀏覽器不支持WebSocket");
        } else {
            // console.log("您的瀏覽器支持WebSocket");
            var toUserId = document.getElementById('toUserId').value;
            var contentText = document.getElementById('contentText').value;
            var msg = '{"sid":"' + toUserId + '","message":"' + contentText + '"}';
            console.log(msg);
            socket.send(msg);
        }
    }*/

</script>
</html>

測(cè)試

運(yùn)行服務(wù)器,打開(kāi)HTML文件,并開(kāi)啟瀏覽器控制臺(tái),打開(kāi)上篇文章中的Qt客戶端項(xiàng)目向后端服務(wù)器發(fā)送一個(gè)消息,

springboot websocket給前端發(fā)消息需要異步嗎,spring boot,websocket,后端

可以看到Qt客戶端向后端服務(wù)器發(fā)送一個(gè)消息的同時(shí),瀏覽器控制臺(tái)也接收到一個(gè)消息。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-840477.html

到了這里,關(guān)于Springboot整合WebSocket實(shí)現(xiàn)主動(dòng)向前端推送消息的文章就介紹完了。如果您還想了解更多內(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)文章

  • Java:SpringBoot整合WebSocket實(shí)現(xiàn)服務(wù)端向客戶端推送消息

    Java:SpringBoot整合WebSocket實(shí)現(xiàn)服務(wù)端向客戶端推送消息

    思路: 后端通過(guò)websocket向前端推送消息,前端統(tǒng)一使用http協(xié)議接口向后端發(fā)送數(shù)據(jù) 本文僅放一部分重要的代碼,完整代碼可參看github倉(cāng)庫(kù) websocket 前端測(cè)試 :http://www.easyswoole.com/wstool.html 依賴 項(xiàng)目目錄 完整依賴 配置 WebSocketServer.java 前端頁(yè)面 websocket.html 前端邏輯 index.js 參

    2024年02月04日
    瀏覽(29)
  • websockets-后端主動(dòng)向前端推送消息

    websockets-后端主動(dòng)向前端推送消息

    公司領(lǐng)導(dǎo)提出了一個(gè)新的需求,那就是部門(mén)主管在有審批消息的情況下,需要看到提示消息。其實(shí)這種需求最簡(jiǎn)單的方法使接入短信、郵件、公眾號(hào)平臺(tái)。直接推送消息。但是,由于使自研項(xiàng)目,公司領(lǐng)導(dǎo)不想花錢(qián),只能另辟蹊徑。 WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。

    2024年02月09日
    瀏覽(22)
  • SpringBoot+Netty+Websocket實(shí)現(xiàn)消息推送

    SpringBoot+Netty+Websocket實(shí)現(xiàn)消息推送

    這樣一個(gè)需求:把設(shè)備異常的狀態(tài)每10秒推送到頁(yè)面并且以彈窗彈出來(lái),這個(gè)時(shí)候用Websocket最為合適,今天主要是后端代碼展示。 添加依賴 定義netty端口號(hào) netty服務(wù)器 Netty配置 管理全局Channel以及用戶對(duì)應(yīng)的channel(推送消息) 管道配置 自定義CustomChannelHandler 推送消息接口及

    2024年02月04日
    瀏覽(19)
  • 服務(wù)端(后端)主動(dòng)通知前端的實(shí)現(xiàn):WebSocket(springboot中使用WebSocket案例)

    我們都知道 http 協(xié)議只能瀏覽器單方面向服務(wù)器發(fā)起請(qǐng)求獲得響應(yīng),服務(wù)器不能主動(dòng)向?yàn)g覽器推送消息。想要實(shí)現(xiàn)瀏覽器的主動(dòng)推送有兩種主流實(shí)現(xiàn)方式: 輪詢:缺點(diǎn)很多,但是實(shí)現(xiàn)簡(jiǎn)單 websocket:在瀏覽器和服務(wù)器之間建立 tcp 連接,實(shí)現(xiàn)全雙工通信 springboot 使用 websocket 有

    2023年04月14日
    瀏覽(36)
  • 前端實(shí)現(xiàn)消息推送、即時(shí)通信、SSE、WebSocket、http簡(jiǎn)介

    前端實(shí)現(xiàn)消息推送、即時(shí)通信、SSE、WebSocket、http簡(jiǎn)介

    服務(wù)端主動(dòng)向客戶端推送消息,使客戶端能夠即時(shí)接收到信息。 場(chǎng)景 頁(yè)面接收到點(diǎn)贊,消息提醒 聊天功能 彈幕功能 實(shí)時(shí)更新數(shù)據(jù)功能 短輪詢 瀏覽器(客戶端)每隔一段時(shí)間向服務(wù)器發(fā)送http請(qǐng)求,服務(wù)器端在收到請(qǐng)求后,不論是否有數(shù)據(jù)更新,都直接進(jìn)行響應(yīng)。 本質(zhì):客

    2024年02月16日
    瀏覽(18)
  • Springboot集成websocket實(shí)現(xiàn)消息推送和在線用戶統(tǒng)計(jì)

    Springboot集成websocket實(shí)現(xiàn)消息推送和在線用戶統(tǒng)計(jì)

    在啟動(dòng)類(lèi)上添加一個(gè)bean 核心代碼 實(shí)現(xiàn)消息推送只要在業(yè)務(wù)代碼中調(diào)用sendMessageSpecial()方法即可。 然后調(diào)用剛才的業(yè)務(wù)接口測(cè)試:http://localhost:8080/websocket/t1 調(diào)用成功后可以看到三個(gè)窗口中都收到了消息

    2023年04月08日
    瀏覽(26)
  • SpringBoot集成WebSocket實(shí)現(xiàn)消息實(shí)時(shí)推送(提供Gitee源碼)

    前言:在最近的工作當(dāng)中,客戶反應(yīng)需要實(shí)時(shí)接收消息提醒,這個(gè)功能雖然不大,但不過(guò)也用到了一些新的技術(shù),于是我這邊寫(xiě)一個(gè)關(guān)于我如何實(shí)現(xiàn)這個(gè)功能、編寫(xiě)、測(cè)試到部署服務(wù)器,歸納到這篇博客中進(jìn)行總結(jié)。 目錄 一、什么是WebSocket 二、后端實(shí)現(xiàn) 2.1、引入pom.xml依賴

    2024年02月11日
    瀏覽(24)
  • 【Java】SpringBoot快速整合WebSocket實(shí)現(xiàn)客戶端服務(wù)端相互推送信息

    【Java】SpringBoot快速整合WebSocket實(shí)現(xiàn)客戶端服務(wù)端相互推送信息

    目錄 什么是webSocket? webSocket可以用來(lái)做什么? WebSocket操作類(lèi) 一:測(cè)試客戶端向服務(wù)端推送消息 1.啟動(dòng)SpringBoot項(xiàng)目 2.打開(kāi)網(wǎng)站 3.進(jìn)行測(cè)試消息推送 4.后端進(jìn)行查看測(cè)試結(jié)果 二:測(cè)試服務(wù)端向客戶端推送消息 1.接口代碼 2.使用postman進(jìn)行調(diào)用 3.查看測(cè)試結(jié)果 ????????WebSocke

    2024年01月20日
    瀏覽(37)
  • SpringBoot集成WebSocket,實(shí)現(xiàn)后臺(tái)向前端推送信息

    SpringBoot集成WebSocket,實(shí)現(xiàn)后臺(tái)向前端推送信息

    在一次項(xiàng)目開(kāi)發(fā)中,使用到了Netty網(wǎng)絡(luò)應(yīng)用框架,以及MQTT進(jìn)行消息數(shù)據(jù)的收發(fā),這其中需要后臺(tái)來(lái)將獲取到的消息主動(dòng)推送給前端,于是就使用到了MQTT,特此記錄一下。 WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議。它實(shí)現(xiàn)了客戶端與服務(wù)器全雙工通信,學(xué)過(guò)計(jì)算機(jī)網(wǎng)絡(luò)都知道

    2024年01月16日
    瀏覽(18)
  • Spring Boot進(jìn)階(48):【實(shí)戰(zhàn)教程】SpringBoot集成WebSocket輕松實(shí)現(xiàn)實(shí)時(shí)消息推送

    Spring Boot進(jìn)階(48):【實(shí)戰(zhàn)教程】SpringBoot集成WebSocket輕松實(shí)現(xiàn)實(shí)時(shí)消息推送

    ????????WebSocket是一種新型的通信協(xié)議,它可以在客戶端與服務(wù)器端之間實(shí)現(xiàn)雙向通信,具有低延遲、高效性等特點(diǎn),適用于實(shí)時(shí)通信場(chǎng)景。在SpringBoot應(yīng)用中,集成WebSocket可以方便地實(shí)現(xiàn)實(shí)時(shí)通信功能,如即時(shí)聊天、實(shí)時(shí)數(shù)據(jù)傳輸?shù)取?????????本文將介紹如何在Sprin

    2024年02月09日
    瀏覽(97)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包