日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

環境:Springboot3.0.5

WebSocket介紹

WebSocket協議RFC 6455提供了一種標準化的方式,通過一個TCP連接在客戶端和服務器之間建立全雙工、雙向的通信通道。它是一個不同于HTTP的TCP協議,但設計為在HTTP之上工作,使用80和443端口,并允許重用現有的防火墻規則。

WebSocket交互開始于一個HTTP請求,使用HTTP Upgrade header進行升級,在本例中是切換到WebSocket協議。下面的例子展示了這種交互:

GET /spring-websocket-portfolio/portfolio HTTP/1.1
Host: localhost:8080
Upgrade: websocket             // ①
Connection: Upgrade           // ②
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

①:Upgrade header頭部信息

②:使用 Upgrade 連接

支持WebSocket的服務器會返回類似下面的輸出,而不是通常的200狀態碼:

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

握手成功后,HTTP upgrade請求的TCP套接字保持打開,客戶端和服務器可以繼續發送和接收消息。

如果WebSocket服務器運行在web服務器(例如Nginx)后面,你可能需要配置它來將WebSocket升級請求傳遞給WebSocket服務器。同樣,如果應用程序運行在云環境中,請查看云提供商提供的有關WebSocket支持的說明。

HTTP與WebSocket

盡管WebSocket在設計上是與HTTP兼容的,而且從HTTP請求開始,但重要的是要明白,這兩種協議導致了非常不同的架構和應用程序編程模型。

在HTTP和REST中,應用程序被建模為多個url。為了與應用程序交互,客戶端以請求-響應的方式訪問這些url。服務器根據HTTP URL、方法和首部將請求路由到適當的處理程序。

相比之下,在websocket中,初始連接通常只有一個URL。隨后,所有應用程序消息都在同一個TCP連接上流動。這是一種完全不同的異步、事件驅動的消息傳遞架構。

WebSocket也是一種底層傳輸協議,與HTTP不同,它對消息內容沒有任何語義規定。這意味著除非客戶端和服務器在消息語義上達成一致,否則無法路由或處理消息。

WebSocket客戶端和服務器可以通過HTTP握手請求的Sec-WebSocket-Protocol頭部來協商使用更高級別的消息傳遞協議(例如STOMP)。在這種情況下,他們需要制定自己的慣例。

什么時候該使用WebSocket

WebSockets可以使網頁具有動態性和交互性。然而,在許多情況下,Ajax和HTTP流或長輪詢的組合可以提供簡單而有效的解決方案。

例如,新聞、郵件和社交源需要動態更新,但每隔幾分鐘更新一次完全沒問題。另一方面,協作、游戲和金融應用需要更接近實時。

延遲本身并不是決定性因素。如果消息量相對較少(例如監視網絡故障),HTTP流或輪詢可以提供有效的解決方案。低延遲、高頻率和高容量的組合才是WebSocket的最佳選擇。

還要記住,在互聯網上,你無法控制的限制性代理可能會阻止WebSocket交互,要么是因為它們沒有配置為傳遞Upgrade header,要么是因為它們關閉了看起來空閑的長連接。這意味著對防火墻內的內部應用程序使用WebSocket比面向公眾的應用程序更直接。

WebSocket核心API

Spring框架提供了一個WebSocket API,可以用它來編寫處理WebSocket消息的客戶端和服務器端應用程序。

  • WebSocketHandler

創建WebSocket服務器很簡單,只需實現WebSocketHandler,或者擴展TextWebSocketHandler或BinaryWebSocketHandler。下面的例子使用了TextWebSocketHandler:

public class MessageHandler extends TextWebSocketHandler {


  @Override
  public void handleTextMessage(WebSocketSession session, TextMessage message) {
    System.out.printf("SessionId: %s, 接收到消息: %s%n", session.getId(), message.getPayload()) ;
    try {
      session.sendMessage(new TextMessage("服務端接收到消息 - " + message.getPayload())) ;
    } catch (IOException e) {
      e.printStackTrace();
    }
  }


  @Override
  public void afterConnectionEstablished(WebSocketSession session) throws Exception {
    System.out.printf("連接成功, 會話Id: %s, Attribute: %s%n", session.getId(), session.getAttributes()) ;
  }


  @Override
  public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
    System.out.printf("連接關閉, 會話Id: %s, 關閉狀態: %s%n", session.getId(), status.getCode() + " - " + status.getReason()) ;
  }


}

WebSocket配置

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {


  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry.addHandler(messageHandler(), "/message")
  }
  @Bean
  public WebSocketHandler messageHandler() {
    return new MessageHandler();
  }
}
  • WebSocket Handshake

要定制初始的HTTP WebSocket握手請求,最簡單的方法是使用HandshakeInterceptor,它提供了握手前和握手后的方法。你可以使用這樣的攔截器來阻止握手,或者讓 WebSocketSession可以訪問任何屬性。下面的例子使用內置的攔截器將HTTP會話屬性傳遞給WebSocket會話:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {


  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry
      .addHandler(messageHandler(), "/message")
      .setHandshakeHandler(handshakeHandler())
      // 添加捂手攔截器
      .addInterceptors(new HandshakeInterceptor() {
        // 如果該方法返回false,則不允許建立連接
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
            WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
          // todo
          attributes.put("uid", uid) ;
          return true ;
        }
        @Override
        public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception exception) {
          // todo
        }
      }) ;
  }
}
  • 部署

Spring WebSocket API很容易集成到Spring MVC應用程序中,DispatcherServlet可以同時處理HTTP WebSocket握手和其他HTTP請求。調用
WebSocketHttpRequestHandler也很容易集成到其他HTTP處理場景中。這樣既方便又容易理解。但是,對于JSR-356運行時,需要特別注意。

JAVA WebSocket API (JSR-356)提供兩種部署機制。第一種方法涉及啟動時的Servlet容器類路徑掃描(Servlet 3特性)@ServerEndpoint。另一個是Servlet容器初始化時使用的注冊 API(ServletContAInerInitializer)。這兩種機制都不可能對所有HTTP處理使用單個“前端控制器” — 包括WebSocket握手和所有其他HTTP請求 — 如Spring MVC的DispatcherServlet。

這是JSR-356的一個重要限制,Spring的WebSocket支持通過特定于服務器的RequestUpgradeStrategy實現來解決這個問題,即使運行在JSR-356運行時也是如此。Tomcat、Jetty、GlassFish、WebLogic、WebSphere和Undertow(以及WildFly)目前都存在這樣的策略。

  • 服務配置

每個底層WebSocket引擎都公開了控制運行時特征的配置屬性,例如消息緩沖區大小、空閑超時等。

對于Tomcat、WildFly和GlassFish,可以在WebSocket Java配置中添加
ServletServerContainerFactoryBean,如下面的例子所示:

@Bean
public ServletServerContainerFactoryBean servletServerContainerFactoryBean() {
  ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean() ;
  container.setMaxTextMessageBufferSize(8192) ;
  container.setMaxBinaryMessageBufferSize(8192) ;
  return container ;
}

 

  • 允許的來源

從Spring Framework 4.1.5開始,WebSocket和SockJS的默認行為是只接受同源請求。也可以允許所有或指定的來源列表。這個檢查主要是為瀏覽器客戶端設計的。沒有什么能阻止其他類型的客戶端修改Origin首部值。

三種可能的行為是:

  1. 僅允許同源請求(默認):在這種模式下,當啟用SockJS時,Iframe HTTP響應頭X-Frame-Options設置為SAMEORIGIN,并且禁用JSONP傳輸,因為它不允許檢查請求的來源。因此,啟用此模式時,不支持IE6和IE7。
  2. 允許指定的來源列表:每個允許的來源必須以http://或https://.開頭在此模式下,當啟用SockJS時,禁用IFrame傳輸。因此,啟用此模式時,將不支持IE6到IE9。
  3. 允許所有來源:要啟用此模式,你應該提供*作為允許的來源值。在該模式下,所有傳輸通道都可用。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {


  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    registry
      .addHandler(messageHandler(), "/message")
      .setAllowedOriginPatterns("*") ;
  }
}

測試

通過上面的介紹和配置,WebSocket環境就算是簡單的配置完成了,接下來通過Postman進行測試。

圖片圖片

連接成功

發送消息及接收消息發送消息及接收消息

 

服務端接收到消息服務端接收到消息

 

分享到:
標簽:SpringBoot
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定