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

SpringBoot+WebSocket實現(xiàn)消息推送功能

 更新時間:2022年08月09日 16:37:15   作者:劍圣無痕  
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡協(xié)議。本文將通過SpringBoot集成WebSocket實現(xiàn)消息推送功能,感興趣的可以了解一下

背景

項目中經(jīng)常會用到消息推送功能,關于推送技術的實現(xiàn),我們通常會聯(lián)想到輪詢、comet長連接技術,雖然這些技術能夠實現(xiàn),但是需要反復連接,對于服務資源消耗過大,隨著技術的發(fā)展,HtML5定義了WebSocket協(xié)議,能更好的節(jié)省服務器資源和帶寬,并且能夠更實時地進行通訊。本文將介紹如何采用websocket實現(xiàn)消息推送。

WebSocket簡介

WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡協(xié)議。它實現(xiàn)了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發(fā)送信息給客戶端。瀏覽器和服務器僅需一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。

協(xié)議原理

Websocket協(xié)議基于Http協(xié)議,針對Http協(xié)議進行了相關的改善,且Websocket協(xié)議也需要建立TCP連接來實現(xiàn)數(shù)據(jù)傳輸,具體實現(xiàn)如下圖:

說明:

  • 客戶端發(fā)起http請求,經(jīng)過3次握手后,建立起TCP連接;http請求里存放WebSocket支持的版本號等信息,如:Upgrade、Connection、WebSocket-Version等。
  • 服務器收到客戶端的握手請求后,同樣采用HTTP協(xié)議回饋數(shù)據(jù)
  • 客戶端收到連接成功的消息后,開始借助于TCP傳輸信道進行全雙工通信.

WebSocket與HTTP協(xié)議的區(qū)別

相同點:都是一樣基于TCP的,都是可靠性傳輸協(xié)議。都是應用層協(xié)議。

不同點:

  • WebSocket是雙向通信協(xié)議,可以雙向發(fā)送或接受信息,而HTTP是單向協(xié)議
  • WebSocket需要瀏覽器和服務器握手進行建立連接的,而http是瀏覽器發(fā)起向服務器的連接。

WebSocket特點

  • 建立在TCP協(xié)議之上,服務器端的實現(xiàn)比較容易。
  • 數(shù)據(jù)格式比較輕量,性能開銷小,通信高效。
  • 支持多種數(shù)據(jù)格式,可以發(fā)送文本、二進制數(shù)據(jù)。
  • 客戶端可以與任意服務器通信,無同源限制。

應用場景

  • 即時聊天通信
  • 在線協(xié)同編輯/編輯
  • 實時數(shù)據(jù)流的拉取與推送
  • 實時地圖位置

系統(tǒng)集成Websocket

jar包引入

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.4.RELEASE</version>
    <relativePath/>
 </parent>
 
  <dependency>
      <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>

Websocket配置

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

具體實現(xiàn)

@ServerEndpoint(value="/websocket/{uid}")
@Component
public class WebSocketServer
{
    private Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
    
    private static final AtomicInteger onlineCount = new AtomicInteger(0);
    
    private static CopyOnWriteArraySet<Session> sessionSet = new CopyOnWriteArraySet<Session>();
    
    @OnOpen
    public void onOpen(Session session,@PathParam("uid") String uid) 
    {
        logger.info("open message uid:{}",uid);
        sessionSet.add(session);
        onlineCount.incrementAndGet();
        logger.info("窗口開始監(jiān)聽uid:{},當前在線人數(shù):{}",uid,onlineCount);
    }
    
    @OnClose
    public void onClose(Session session) 
    {
        String sessionId=session.getId();
        logger.info("sessionid:{} close",sessionId);
        sessionSet.remove(this);
        int count=onlineCount.decrementAndGet();
        logger.info("有一連接關閉!當前在線人數(shù)為:{}",count);
    }

    @OnError
    public void onError(Session session, Throwable error) 
    {
        logger.error("消息發(fā)生錯誤:{},Session ID: {}",error.getMessage(),session.getId());
    }
    
   
    public void batchSendMesasge(String uid,String message) throws IOException 
    {
        logger.info("推送消息到窗口:{},推送內容:{}",uid,message);
        for(Session session:sessionSet){
            sendMessage(session, message);
        }
    }
    
    public void sendMessage(Session session, String message) throws IOException {
        
        if(session!=null)
        {
            synchronized (session) {
                session.getBasicRemote().sendText(message);
            }
        }
    }

}

說明: @OnOpen :當有新的WebSocket連接進入時調用 @OnClose:當有WebSocket連接關閉時調用 @OnError :當有WebSocket拋出異常時調用 @OnMessage:當接收到字符串消息時,對該方法進行回調

測試示例

@Controller
public class WebScoketController
{
   @Autowired
   private WebSocketServer webSocketServer;
  
    @ResponseBody
    @RequestMapping("/sendMessage")
    public String batchMessage(String uid,String message) 
    {  
        Map<String, String> map =new HashMap<String, String>();
        try 
        {
            map.put("code", "200");
            webSocketServer.batchSendMesasge(uid,message);
        } 
        catch (Exception e) 
        {
            map.put("code", "-1");
            map.put("message", e.getMessage());
        }
        return JSON.toJSONString(map);
    } 
    
    @GetMapping("/enter")
    public String enter() 
    { 
        return "webscoketTest.html";
    }
}

頁面請求websocket

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>websocket test</title>
    
      <script type="text/javascript">
            if ("WebSocket" in window)
            {
            	console.log("您的瀏覽器支持 WebSocket!");
               
               var ws = new WebSocket("ws://127.0.0.1:9092/websocket/1234");
               console.log('ws連接狀態(tài):' + ws.readyState);
               
               //打開
               ws.onopen = function()
               {
                  ws.send("message test");
                  console.log("mesage sending");
               };
                
                //發(fā)送消息
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                  alert(received_msg);
               };
                
                //關閉
               ws.onclose = function()
               { 
                  // 關閉 websocket
                  console.log("socket is close"); 
               };
            }
            
            else
            {
            	 console.log("您的瀏覽器不支持 WebSocket!");
            }
      </script>
   </head>
</html>

測試效果

啟動程序:運行http://localhost:9092/enter 進入頁面開啟websocket。

用戶發(fā)送消息:http://localhost:9092/sendMessage?uid=1235&message=this%20is%20message1

執(zhí)行的結果如下:

 open message uid:1234
 [nio-9092-exec-2] c.s.f.w.controller.WebSocketServer: 窗口開始監(jiān)聽uid:1234,當前在線人數(shù):1
 [nio-9092-exec-5] c.s.f.w.controller.WebSocketServer: 推送消息到窗口:1234,推送內容:this is message

以上就是SpringBoot+WebSocket實現(xiàn)消息推送功能的詳細內容,更多關于SpringBoot WebSocket消息推送的資料請關注腳本之家其它相關文章!

相關文章

  • Springboot如何實現(xiàn)自定義異常數(shù)據(jù)

    Springboot如何實現(xiàn)自定義異常數(shù)據(jù)

    這篇文章主要介紹了Springboot如何實現(xiàn)自定義異常數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • 如何將DeepSeek 集成到 Java 的 Spring Boot 項目中

    如何將DeepSeek 集成到 Java 的 Spring Boot&

    本文介紹了如何將DeepSeek集成到Java的SpringBoot項目中,包括準備工作、集成步驟和示例說明,感興趣的朋友一起看看吧
    2025-02-02
  • Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置

    Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置

    在微服務搭建中經(jīng)常會使用到多數(shù)據(jù)庫情形這個時候,下面這篇文章主要給大家介紹了關于Java實戰(zhàn)之用hutool-db實現(xiàn)多數(shù)據(jù)源配置的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • java基于JSON實現(xiàn)前后端交互(附代碼)

    java基于JSON實現(xiàn)前后端交互(附代碼)

    本文主要介紹了java基于JSON實現(xiàn)前后端交互,通過實際代碼示例展示了如何前后端JSON交互,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • HashMap 和 Hashtable的區(qū)別

    HashMap 和 Hashtable的區(qū)別

    本文主要介紹HashMap 和 Hashtable的區(qū)別,這里整理了相關資料并詳細介紹了HashMap 和 Hashtable的區(qū)別及其工作原理和使用方法,有需要的朋友可以看一下
    2016-09-09
  • 在SpringBoot中實現(xiàn)線程池并行處理任務的方法詳解

    在SpringBoot中實現(xiàn)線程池并行處理任務的方法詳解

    在使用Spring Boot開發(fā)應用程序時,我們經(jīng)常需要處理一些耗時的任務,例如網(wǎng)絡請求、數(shù)據(jù)庫操作或者其他需要花費一定時間的計算任務,本文將介紹如何在Spring Boot中使用線程池來實現(xiàn)任務的并行處理
    2023-06-06
  • spark中使用groupByKey進行分組排序的示例代碼

    spark中使用groupByKey進行分組排序的示例代碼

    這篇文章主要介紹了spark中使用groupByKey進行分組排序的實例代碼,本文通過實例代碼給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • mybatis的mapper.xml中resultMap標簽的使用詳解

    mybatis的mapper.xml中resultMap標簽的使用詳解

    這篇文章主要介紹了mybatis的mapper.xml中resultMap標簽的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06
  • Springboot AOP對指定敏感字段數(shù)據(jù)加密存儲的實現(xiàn)

    Springboot AOP對指定敏感字段數(shù)據(jù)加密存儲的實現(xiàn)

    本篇文章主要介紹了利用Springboot+AOP對指定的敏感數(shù)據(jù)進行加密存儲以及對數(shù)據(jù)中加密的數(shù)據(jù)的解密的方法,代碼詳細,具有一定的價值,感興趣的小伙伴可以了解一下
    2021-11-11
  • SpringBoot中的文件上傳與下載詳解

    SpringBoot中的文件上傳與下載詳解

    這篇文章主要介紹了SpringBoot中的文件上傳與下載詳解,springboot是spring家族中的一個全新框架,用來簡化spring程序的創(chuàng)建和開發(fā)過程,本文我們就一起來看看上傳與下載的操作,需要的朋友可以參考下
    2023-08-08

最新評論

大悟县| 和政县| 华宁县| 元阳县| 五常市| 台北市| 郑州市| 阿合奇县| 庆安县| 临朐县| 江安县| 同德县| 慈溪市| 龙岩市| 桐庐县| 水富县| 琼中| 汽车| 和政县| 平顶山市| 丰县| 广东省| 大冶市| 锦州市| 阿勒泰市| 辉南县| 墨脱县| 习水县| 揭东县| 康平县| 射洪县| 济阳县| 改则县| 昭平县| 南华县| 剑川县| 闵行区| 平塘县| 晋中市| 乐昌市| 青浦区|