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

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

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

背景

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

WebSocket簡介

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

協(xié)議原理

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

說明:

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

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

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

不同點:

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

WebSocket特點

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

應(yīng)用場景

  • 即時聊天通信
  • 在線協(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:{},當(dāng)前在線人數(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("有一連接關(guān)閉!當(dāng)前在線人數(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("推送消息到窗口:{},推送內(nèi)容:{}",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 :當(dāng)有新的WebSocket連接進入時調(diào)用 @OnClose:當(dāng)有WebSocket連接關(guān)閉時調(diào)用 @OnError :當(dāng)有WebSocket拋出異常時調(diào)用 @OnMessage:當(dāng)接收到字符串消息時,對該方法進行回調(diào)

測試示例

@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);
               };
                
                //關(guān)閉
               ws.onclose = function()
               { 
                  // 關(guān)閉 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í)行的結(jié)果如下:

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

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

相關(guān)文章

  • Java中volatile關(guān)鍵字實現(xiàn)原理

    Java中volatile關(guān)鍵字實現(xiàn)原理

    本文詳細解讀一下volatile關(guān)鍵字如何保證變量在多線程之間的可見性,對Java中volatile關(guān)鍵字實現(xiàn)原理感興趣的朋友一起通過本文學(xué)習(xí)吧
    2017-06-06
  • java實現(xiàn)面板之間切換功能

    java實現(xiàn)面板之間切換功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)面板之間切換功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    PowerJob分布式任務(wù)調(diào)度源碼流程解讀

    這篇文章主要為大家介紹了PowerJob分布式任務(wù)調(diào)度源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-02-02
  • Java使用for循環(huán)解決經(jīng)典的雞兔同籠問題示例

    Java使用for循環(huán)解決經(jīng)典的雞兔同籠問題示例

    這篇文章主要介紹了Java使用for循環(huán)解決經(jīng)典的雞兔同籠問題,結(jié)合實例形式分析了Java巧妙使用流程控制語句for循環(huán)解決雞兔同籠問題相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • 半小時通透Java的泛型

    半小時通透Java的泛型

    這篇文章主要給大家介紹了關(guān)于Java中泛型使用的方法,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • Java控制臺實現(xiàn)猜拳游戲

    Java控制臺實現(xiàn)猜拳游戲

    這篇文章主要為大家詳細介紹了Java控制臺實現(xiàn)猜拳游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • springboot 實現(xiàn)mqtt物聯(lián)網(wǎng)的示例代碼

    springboot 實現(xiàn)mqtt物聯(lián)網(wǎng)的示例代碼

    這篇文章主要介紹了springboot 實現(xiàn)mqtt物聯(lián)網(wǎng),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 詳解java模板和回調(diào)機制

    詳解java模板和回調(diào)機制

    這篇文章主要為大家詳細介紹了java模板和回調(diào)機制,學(xué)習(xí)java模板,感興趣的朋友可以參考一下
    2016-03-03
  • Java數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)

    Java數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)

    下面小編就為大家?guī)硪黄狫ava數(shù)據(jù)庫連接_jdbc-odbc橋連接方式(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Java設(shè)計模式之觀察者模式

    Java設(shè)計模式之觀察者模式

    這篇文章主要為大家介紹了Java觀察者模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12

最新評論