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

Java后端向前端推送消息完整代碼實(shí)例

 更新時(shí)間:2026年02月02日 10:05:28   作者:recollection℡1??  
WebSocket是一種全雙工通信協(xié)議,允許后端主動(dòng)向前端推送消息,下面這篇文章主要介紹了Java后端向前端推送消息的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

1、WebSocketConfig配置類(lèi)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

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

2、WebSocket消息發(fā)送接收

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@ServerEndpoint(value = "/web/{id}")
public class WebSocketProcess {

    /*
     * 持有每個(gè)webSocket對(duì)象,以key-value存儲(chǔ)到線(xiàn)程安全ConcurrentHashMap,
     */
    private static ConcurrentHashMap<Long, WebSocketProcess> concurrentHashMap = new ConcurrentHashMap<>(12);

    /**
     * 會(huì)話(huà)對(duì)象
     **/
    private Session session;


    /*
     * 客戶(hù)端創(chuàng)建連接時(shí)觸發(fā)
     * */
    @OnOpen
    public void onOpen(Session session, @PathParam("id") long id) {
        //每新建立一個(gè)連接,就把當(dāng)前客戶(hù)id為key,this為value存儲(chǔ)到map中
        this.session = session;
        concurrentHashMap.put(id, this);
        log.info("Open a websocket. id={}", id);
    }

    /**
     * 客戶(hù)端連接關(guān)閉時(shí)觸發(fā)
     **/
    @OnClose
    public void onClose(Session session, @PathParam("id") long id) {
        //客戶(hù)端連接關(guān)閉時(shí),移除map中存儲(chǔ)的鍵值對(duì)
        concurrentHashMap.remove(id);
        log.info("close a websocket, concurrentHashMap remove sessionId= {}", id);
    }

    /**
     * 接收到客戶(hù)端消息時(shí)觸發(fā)
     */
    @OnMessage
    public void onMessage(String message, @PathParam("id") String id) {
        log.info("receive a message from client id={},msg={}", id, message);
    }

    /**
     * 連接發(fā)生異常時(shí)候觸發(fā)
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("Error while websocket. ", error);
    }

    /**
     * 發(fā)送消息到指定客戶(hù)端
     *
     * @param id
     * @param message
     */
    public void sendMessage(long id, String message) throws Exception {
        //根據(jù)id,從map中獲取存儲(chǔ)的webSocket對(duì)象
        WebSocketProcess webSocketProcess = concurrentHashMap.get(id);
        if (!ObjectUtils.isEmpty(webSocketProcess)) {
            //當(dāng)客戶(hù)端是Open狀態(tài)時(shí),才能發(fā)送消息
            if (webSocketProcess.session.isOpen()) {
                webSocketProcess.session.getBasicRemote().sendText(message);
            } else {
                log.error("websocket session={} is closed ", id);
            }
        } else {
            log.error("websocket session={} is not exit ", id);
        }
    }

    /**
     * 發(fā)送消息到所有客戶(hù)端
     */
    public void sendAllMessage(String msg) throws Exception {
        log.info("online client count={}", concurrentHashMap.size());
        Set<Map.Entry<Long, WebSocketProcess>> entries = concurrentHashMap.entrySet();
        for (Map.Entry<Long, WebSocketProcess> entry : entries) {
            Long cid = entry.getKey();
            WebSocketProcess webSocketProcess = entry.getValue();
            boolean sessionOpen = webSocketProcess.session.isOpen();
            if (sessionOpen) {
                webSocketProcess.session.getBasicRemote().sendText(msg);
            } else {
                log.info("cid={} is closed,ignore send text", cid);
            }
        }
    }
}

3、消息推送Controller

import com.xyl.web.controller.common.WebSocketProcess;
import com.xyl.web.controller.common.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/testws")
public class WebSocketController {

    /**
     * 注入WebSocketProcess
     **/
    @Autowired
    private  WebSocketProcess webSocketProcess;

    /**
     * 向指定客戶(hù)端發(fā)消息
     *
     * @param id

     */
    @PostMapping(value = "sendMsgToClientById")
    public void sendMsgToClientById(@RequestParam long id, @RequestParam String text) {
        try {
            webSocketProcess.sendMessage(id, text);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 發(fā)消息到所有客戶(hù)端
     *
     * @param text
     */
    @PostMapping(value = "sendMsgToAllClient")
    public void sendMsgToAllClient(@RequestParam String text) {
        try {
            webSocketProcess.sendAllMessage(text);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     /**
     * 定時(shí)向客戶(hù)端推送消息
     * @throws Exception
     */
    @Scheduled(cron = "0/5 * * * * ?")
    private void configureTasks() throws Exception {
        webSocketProcess.sendAllMessage("向前端推送消息內(nèi)容");
    }
}

4、測(cè)試HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>websocket測(cè)試</title>
    <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
</head>
<body>
<div id="content"></div>

</body>
<script type="text/javascript">

    $(function(){
        var ws;
        //檢測(cè)瀏覽器是否支持webSocket
        if("WebSocket" in window){
            $("#content").html("您的瀏覽器支持webSocket!");
            //模擬產(chǎn)生clientID
            let clientID = Math.ceil(Math.random()*100);

            //創(chuàng)建 WebSocket 對(duì)象,注意請(qǐng)求路徑!?。?!
            ws = new WebSocket("ws://127.0.0.1:9095/web/"+clientID);

            //與服務(wù)端建立連接時(shí)觸發(fā)
            ws.onopen = function(){
                $("#content").append("<p>與服務(wù)端建立連接建立成功!您的客戶(hù)端ID="+clientID+"</p>");

                //模擬發(fā)送數(shù)據(jù)到服務(wù)器
                ws.send("你好服務(wù)端!我是客戶(hù)端 "+clientID);
            }

            //接收到服務(wù)端消息時(shí)觸發(fā)
            ws.onmessage = function (evt) {
                let received_msg = evt.data;
                $("#content").append("<p>接收到服務(wù)端消息:"+received_msg+"</p>");
            };

            //服務(wù)端關(guān)閉連接時(shí)觸發(fā)
            ws.onclose = function() {
                console.error("連接已經(jīng)關(guān)閉.....")
            };
        }else{
            $("#content").html("您的瀏覽器不支持webSocket!");
        }
    })

</script>
</html>


總結(jié) 

到此這篇關(guān)于Java后端向前端推送消息完整代碼的文章就介紹到這了,更多相關(guān)Java后端向前端推送消息內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java8 使用CompletableFuture 構(gòu)建異步應(yīng)用方式

    Java8 使用CompletableFuture 構(gòu)建異步應(yīng)用方式

    這篇文章主要介紹了Java8 使用CompletableFuture 構(gòu)建異步應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中集成ELK的使用小結(jié)

    Java中集成ELK的使用小結(jié)

    本文系統(tǒng)講解ELK在Java應(yīng)用中的應(yīng)用,涵蓋日志收集、過(guò)濾、監(jiān)控、集群部署及性能優(yōu)化,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-08-08
  • java批量導(dǎo)入Excel數(shù)據(jù)超詳細(xì)實(shí)例

    java批量導(dǎo)入Excel數(shù)據(jù)超詳細(xì)實(shí)例

    這篇文章主要給大家介紹了關(guān)于java批量導(dǎo)入Excel數(shù)據(jù)的相關(guān)資料,EXCEL導(dǎo)入就是文件導(dǎo)入,操作代碼是一樣的,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-08-08
  • JavaWeb編程 Servlet的基本配置

    JavaWeb編程 Servlet的基本配置

    本文講的是Servlet最基本的配置信息,相信對(duì)你一定有幫助
    2013-11-11
  • Springboot集成RabbitMQ死信隊(duì)列的實(shí)現(xiàn)

    Springboot集成RabbitMQ死信隊(duì)列的實(shí)現(xiàn)

    在大多數(shù)的MQ中間件中,都有死信隊(duì)列的概念。本文主要介紹了Springboot集成RabbitMQ死信隊(duì)列的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 詳解SpringMVC組件之HandlerMapping(一)

    詳解SpringMVC組件之HandlerMapping(一)

    這篇文章主要介紹了詳解SpringMVC組件之HandlerMapping(一),HandlerMapping組件是Spring?MVC核心組件,用來(lái)根據(jù)請(qǐng)求的request查找對(duì)應(yīng)的Handler,在Spring?MVC中,有各式各樣的Web請(qǐng)求,每個(gè)請(qǐng)求都需要一個(gè)對(duì)應(yīng)的Handler來(lái)處理,需要的朋友可以參考下
    2023-08-08
  • java實(shí)現(xiàn)MD5加密方法匯總

    java實(shí)現(xiàn)MD5加密方法匯總

    本文給大家匯總介紹了2種java實(shí)現(xiàn)MD5加密的方法,非常的實(shí)用,這里分享給大家,學(xué)習(xí)下其中的思路,對(duì)大家學(xué)習(xí)java非常有幫助。
    2015-10-10
  • 一起來(lái)看看springboot集成redis的使用注解

    一起來(lái)看看springboot集成redis的使用注解

    這篇文章主要為大家詳細(xì)介紹了springboot集成redis的使用注解,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法

    java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法

    這篇文章主要介紹了java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Lombok @Slf4j log對(duì)象沒(méi)有info等方法不可用問(wèn)題及解決

    Lombok @Slf4j log對(duì)象沒(méi)有info等方法不可用問(wèn)題及解決

    本文主要介紹了如何解決Spring Boot項(xiàng)目中的日志依賴(lài)沖突問(wèn)題,以及如何使用Lombok和SLF4J進(jìn)行日志記錄,Lombok通過(guò)生成Logger對(duì)象簡(jiǎn)化了日志記錄,而SLF4J提供了一個(gè)統(tǒng)一的日志接口,允許開(kāi)發(fā)者在運(yùn)行時(shí)選擇不同的日志實(shí)現(xiàn)
    2024-12-12

最新評(píng)論

哈巴河县| 贺州市| 遵化市| 和林格尔县| 晋宁县| 阳西县| 大荔县| 定州市| 渑池县| 滁州市| 淮滨县| 类乌齐县| 体育| 旌德县| 广昌县| 南安市| 调兵山市| 泌阳县| 阿拉善左旗| 平塘县| 香港 | 焦作市| 成都市| 思南县| 铁岭县| 太白县| 格尔木市| 阜新市| 西盟| 兴义市| 托里县| 桐乡市| 墨玉县| 姜堰市| 兴山县| 诏安县| 迭部县| 轮台县| 科尔| 胶南市| 丁青县|