91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用SpringBoot+WebSocket實現消息推送功能

發布時間:2022-08-10 09:31:24 來源:億速云 閱讀:159 作者:iii 欄目:開發技術

這篇文章主要講解了“怎么使用SpringBoot+WebSocket實現消息推送功能”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么使用SpringBoot+WebSocket實現消息推送功能”吧!

背景

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

WebSocket簡介

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

協議原理

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

怎么使用SpringBoot+WebSocket實現消息推送功能

說明:

  • 客戶端發起http請求,經過3次握手后,建立起TCP連接;http請求里存放WebSocket支持的版本號等信息,如:Upgrade、Connection、WebSocket-Version等。

  • 服務器收到客戶端的握手請求后,同樣采用HTTP協議回饋數據

  • 客戶端收到連接成功的消息后,開始借助于TCP傳輸信道進行全雙工通信.

WebSocket與HTTP協議的區別

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

不同點:

  • WebSocket是雙向通信協議,可以雙向發送或接受信息,而HTTP是單向協議

  • WebSocket需要瀏覽器和服務器握手進行建立連接的,而http是瀏覽器發起向服務器的連接。

WebSocket特點

  • 建立在TCP協議之上,服務器端的實現比較容易。

  • 數據格式比較輕量,性能開銷小,通信高效。

  • 支持多種數據格式,可以發送文本、二進制數據。

  • 客戶端可以與任意服務器通信,無同源限制。

應用場景

  • 即時聊天通信

  • 在線協同編輯/編輯

  • 實時數據流的拉取與推送

  • 實時地圖位置

系統集成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();
    }
}

具體實現

@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("窗口開始監聽uid:{},當前在線人數:{}",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("有一連接關閉!當前在線人數為:{}",count);
    }

    @OnError
    public void onError(Session session, Throwable error) 
    {
        logger.error("消息發生錯誤:{},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連接狀態:' + ws.readyState);
               
               //打開
               ws.onopen = function()
               {
                  ws.send("message test");
                  console.log("mesage sending");
               };
                
                //發送消息
               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。

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

執行的結果如下:

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

感謝各位的閱讀,以上就是“怎么使用SpringBoot+WebSocket實現消息推送功能”的內容了,經過本文的學習后,相信大家對怎么使用SpringBoot+WebSocket實現消息推送功能這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

吉木乃县| 宁化县| 广德县| 琼结县| 彝良县| 民权县| 鄄城县| 松江区| 乳源| 登封市| 镇原县| 武隆县| 信丰县| 呼图壁县| 巢湖市| 长武县| 寻甸| 通辽市| 都昌县| 伊金霍洛旗| 库尔勒市| 兰坪| 甘肃省| 台江县| 衡山县| 安平县| 达州市| 七台河市| 阿图什市| 周口市| 黄陵县| 龙井市| 石泉县| 绍兴县| 罗田县| 普兰县| 太原市| 垦利县| 西平县| 陆河县| 兴仁县|