Spring 4 官方文檔學習(十四)WebSocket支持


個人提示:如果需要用到頁面推送,高頻且要低延遲,WebSocket無疑是最佳選擇。否則還是輪詢和long polling吧。

做了一個小demo放在碼雲上,有興趣的可以看一下,簡單易懂:websocket-demo


 

本部分覆蓋了web應用中Spring框架對WebSocket-style messaging的支持,包括使用STOMP作為應用及WebSocket子協議。

 

介紹 部分,給出了一個關於WebSocket的框架,覆蓋了adoption challenges、design considerations、以及思考什么時候合適。

WebSocket API 部分,回顧了服務器側Spring WebSocket API。

SockJS Fallback Options 部分,解釋了SockJS協議,以及如何配置和使用它。

STOMP概覽 部分,介紹了STOMP messaging 協議。

在WebSocket上啟用STOMP 部分,演示了如何在Spring中配置STOMP支持。

注解消息處理 部分和后面的部分,解釋了如何編寫注解的消息處理方法、發送消息、選擇消息broker options,以及work with the special "user" destinations(與特別的user目的地一起工作?)。

測試帶注解的Controller方法 部分,列出了測試STOMP/WebSocket應用的三種方式。

 

1、介紹

WebSocket協議 RFC 6455,為web應用定義了一個重要的、全新的能力:全雙工、雙向通信(服務器和客戶端之間)。在經歷了讓web更加交互的這段很長的技術歷史之后,WebSocket是非常激動人心的新功能。(技術歷史:Java Applet、XMLHttpRequest、Adobe Flash、ActiveXObject、不同的Comet技術、服務器發送的事件、等等)

 

對於WebSocket協議的更多介紹不在本文檔范圍之內。但至少,要理解HTTP僅用於初始化握手 -- 依賴於HTTP內建的機制來請求協議升級(或者協議切換)到服務器能夠響應HTTP status 101 (切換協議)-- 當然前提是服務器允許。假定握手成功,HTTP upgrade request底層的TCP socket仍然保持打開狀態,然后服務器和客戶端都能使用它給對方發送消息

 

Spring Framework 4 包含了一個新的spring-websocket模塊 -- 提供了廣泛的WebSocket支持。它兼容Java WebSocket API 標准(JSR-356),也提供了額外的value-add -- 稍后有解釋。

 

1.1、WebSocket Fallback Options

采用WebSocket的一個巨大挑戰是某些瀏覽器不支持WebSocket。第一個支持WebSocket的IE版本是10.更多地,一些限制性的代理可能配置了拒絕HTTP upgrade或會在一段時間后破壞連接。建議看一下這篇文章"How HTML5 Web Sockets Interact With Proxy Servers"

 

因此,今天想要構建一個WebSocket應用的話,要求fallback options 以在需要的時候模擬WebSocket API。Spring Framework提供了這樣的透明的fallback options -- 基於SockJS protocol。這些選項可以通過配置來啟用,不需要修改應用。

 

1.2、一個消息架構

除了來自short-to-midterm adoption的挑戰,使用WebSocket還帶來了重要的設計考慮,that are important to recognize early on, especially in contrast to what we know about building web applications today。

 

在今天,在構建web應用時,REST是一個被廣泛地接受、理解、並支持的架構。該結構依賴於擁有很多URLs、幾個HTTP methods、以及其他規則如使用超媒體(鏈接)、保持無狀態、等等。

 

與此相反,WebSocket應用可能會使用單一的URL來初始化HTTP握手。此后所有的消息會分享和流動在同一個TCP連接上。這是一種完全不同的、異步的、事件驅動的消息架構。更類似與傳統的消息應用(如JMS、AMQP)。

 

Spring Framework 4 包含了一個新的 spring-messaging 模塊,帶有來自Spring Integration項目的關鍵抽象(如Message、MessageChannel、MessageHandler、以及其他能夠作為消息架構基礎的東西)。該模塊還包含了一組注解,可用於將消息映射到方法,類似於Spring MVC基於注解的編程模型。

 

1.3、Sub-Protocol Support in WebSocket -- WebSocket中的子協議支持

WebSocket是一個消息架構,但不強制使用任何特定的消息協議!

它是TCP之上非常薄的一層,會講字節流轉成消息(文本或二進制)流,僅此。它依賴於應用來解釋消息的含義。

 

HTTP是應用層協議,與此不同,在WebSocket協議中在incoming消息中沒有足夠的信息讓框架或容器來明白如何route 或處理它。因此,WebSocket也許不那么低級,但很trivial(零碎)。你可以直接使用它,也可以在上面創建一個框架。這類似於大多數應用都是用web框架,而不直接使用Servlet API。

 

有鑒於此,WebSocket RFC定義了sub-protocols的使用。在握手期間,客戶端和服務器可以使用header Sec-WebSocket-Protocol,來允許使用一個sub-protocol,就是說,一個高級的應用層協議。雖然不要求使用sub-protocol,但是如果不使用,應用仍然需要選擇一種消息格式 -- 服務器和客戶端都懂的。該消息格式可以是自定義、框架特有的、或者標准的消息協議。

 

Spring框架提供了一種支持:使用STOMP,STOMP是一個簡單的消息協議,最早是受HTTP啟發而被創建的腳本語言。

在web上,STOMP被廣泛的支持,且良好地適用於WebSocket。

 

1.4、我應該使用WebSocket嗎?

在圍繞使用WebSocket的設計考慮中,很值得問一句,“什么時候適合使用?”。

在web應用中最適合WebSocket的場景是 客戶端和服務器需要高頻率低延遲交換事件的時候。基本的候選包括但不限於,金融、游戲、合作、以及其他應用。這些應用對時間延遲很敏感,還需要以高頻率交換大量的消息。

 

對其他應用類型,這可能不合適。例如,新聞或社交feed 顯示新聞只需要每隔幾分鍾簡單地poll一下即可。雖然延遲也很重要,但幾分鍾后再顯示也無所謂。

 

甚至在一些延遲要求很嚴格的場景里,例如消息的提交相對較低(如監控網絡失敗的信息),仍然可以考慮使用long polling,因為相對簡單。

 

只有在同時考慮低延遲高頻率消息時,可以使用WebSocket協議。就算這些應用,選擇仍然存在:所有的client-server通信是否通過WebSocket messages來完成,還是使用HTTP和REST來完成?答案是,視情況不同而不同。然而,可能存在某些功能同時由WebSocket和一個REST API來完成,以給客戶端更多選擇。更多地,一個REST API調用可能需要廣播一條消息到感興趣的客戶端 -- 通過WebSocket。

 

Spring框架允許@Controller和@RestController classes擁有HTTP請求處理方法和WebSocket消息處理方法。

一個Spring MVC請求處理方法,或者任何應用方法,都可以輕易的廣播一條消息到所有感興趣的WebSocket客戶端或者到特定的用戶。

 

2、WebSocket API

Spring框架提供了一個WebSocket API,用於適用不同的WebSocket引擎。目前該列表包括了WebSocket runtimes,如:Tomcat 7.0.47+、Jetty 9.1+、GlassFish 4.1+、WebLogic 12.1.3+,以及Undertow 1.0+ (還有WildFly 8.0+)。以后可能添加其他支持。

如同在介紹中所解釋的,直接使用WebSocket API太低級了 -- 除非假定了消息格式,否則框架很難解釋消息或者route它們 -- 通過注解。這就是為什么應該考慮使用Sub-Protocol和Spring的STOMP over WebSocket支持。

當使用一個高級的協議時,WebSocket API的細節變得不相關起來,這和TCP通信的細節沒有暴露在使用HTTP的應用中很相像。無論如何,本部分會覆蓋使用WebSocket的細節。

2.1、創建和配置一個WebSocketHandler

創建一個WebSocket server很簡單,只要實現WebSocketHandler接口,或者繼承TextWebSocketHandler/BinaryWebSocketHandler即可:

import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.TextMessage;

public class MyHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        // ...
    }

}

有一個專用的WebSocket Java-config和XML namespace支持,可以將上面的WebSocket handler映射到特定的URL。

import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

或者:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler"/>
    </websocket:handlers>

    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

上面,是針對Spring MVC 應用的,所以應該包含在DispatcherServlet的配置中。然而,Spring的WebSocket支持不依賴於Spring MVC。通過WebSocketHttpRequestHandler可以非常簡單地將一個WebSocketHandler集成到其他HTTP服務環境。

 

2.2、定制WebSocket握手

定制WebSocket初始化HTTP握手請求的最簡單的辦法是通過一個HandshakeInterceptor,該攔截器暴露了before和after握手方法。該攔截器可以用來阻攔握手或者讓任意attributes可用於WebSocketSession。例如,有一個內建攔截器可以傳遞HTTP session attributes到WebSocket session:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyHandler(), "/myHandler")
            .addInterceptors(new HttpSessionHandshakeInterceptor());
    }

}

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler"/>
        <websocket:handshake-interceptors>
            <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/>
        </websocket:handshake-interceptors>
    </websocket:handlers>

    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

更高級的選項是繼承DefaultHandshakeHandler,它操作了WebSocket握手的步驟,包括驗證client origin、協商一個sub-protocol、等等。一個應用可能也需要使用該選項--如果它需要配置一個自定義的RequestUpgradeStrategy,以使用尚不支持的WebSocket server引擎和版本(2.4部分有更多信息)。Java-config和XML namespace都可以配置自定義的HandshakeHandler。

 

2.3、WebSocketHandler Decoration -- 裝飾?

Spring提供了一個WebSocketHandlerDecorator基類,可以用額外的行為來裝飾一個WebSocketHandler。使用WebSocket Java-config或XML namespace時,默認就添加了日志和異常處理實現。ExceptionWebSocketHandlerDecorator會捕獲任意WebSocketHandler method拋出的所有的未捕獲的異常,還會關閉WebSocket session並使用status 1011 來表明一個服務器錯誤。

 

2.4、部署考慮

Spring WebSocket API可以很簡單地集成到Spring MVC應用中,然后DispatcherServlet會同時服務HTTP WebSocket handshake和其他HTTP請求。

將其集成到其他HTTP處理場景也是一樣的,調用 WebSocketHttpRequestHandler 即可。簡潔易懂。但關於JSR-356 runtimes需要特別的考慮。

 

Java WebSocket API (JSR-356) 提供了兩種部署機制。第一種是使用一個Servlet容器在啟動時進行類路徑掃描(Servlet 3 功能);另一種是在Servlet容器初始化時使用一個注冊API。二者都不能使用單一的前端控制器來處理所有的HTTP -- 包括WebSocket握手和所有其他HTTP請求 -- 例如Spring MVC的DispatcherServlet。

 

這是JSR-356最明顯的限制。-- 翻譯不達意:This is a significant limitation of JSR-356 that Spring’s WebSocket support addresses by providing a server-specific RequestUpgradeStrategy even when running in a JSR-356 runtime.

A request to overcome the above limitation in the Java WebSocket API has been created and can be followed at WEBSOCKET_SPEC-211. Also note that Tomcat and Jetty already provide native API alternatives that makes it easy to overcome the limitation. We are hopeful that more servers will follow their example regardless of when it is addressed in the Java WebSocket API. -- 大意是說請求要越過上面的限制,可以按照標准來創建。另外,Tomcat和Jetty已經提供了原生API可以很簡單地越過限制。

另一個考慮是,希望支持JSR-356的Servlet容器執行一個 ServletContainerInitializer (SCI)掃描 會拖慢應用的啟動,某些情況下非常顯著。當升級到支持JSR-356的Servlet容器版本時,如果觀察到明顯的影響,那應該有選擇的啟用或禁用web碎片(和SCI掃描) -- 使用web.xml中的<absolute-ordering/>元素。如下:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <absolute-ordering/>

</web-app>

你可以有選擇的啟用web碎片--通過名字,例如Spring自己的SpringServletContainerInitializer--它提供了對Servlet 3 Java 初始化 API的支持,如果需要的話。如下:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <absolute-ordering>
        <name>spring_web</name>
    </absolute-ordering>

</web-app>

 

2.5、配置WebSocket引擎

每個底層的WebSocket引擎都會暴露一些配置properties,可以控制運行時特性,例如消息緩沖大小、空閑超時、等等。

 

對於Tomcat、WildFly、還有GlassFish來說,在你的WebSocket Java config中添加一個ServletServerContainerFactoryBean

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

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

}

或者WebSocket XML namespace:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <bean class="org.springframework...ServletServerContainerFactoryBean">
        <property name="maxTextMessageBufferSize" value="8192"/>
        <property name="maxBinaryMessageBufferSize" value="8192"/>
    </bean>

</beans>

對於客戶端側WebSocket配置來說,應該使用WebSocketContainerFactoryBean (XML) 或 ContainerProvider.getWebSocketContainer() (Java config)。

對於Jetty,需要提供一個預配置的Jetty WebSocketServerFactory,並通過你的WebSocket Java config將其插入到Spring的DefaultHandshakeHandler:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(echoWebSocketHandler(),
            "/echo").setHandshakeHandler(handshakeHandler());
    }

    @Bean
    public DefaultHandshakeHandler handshakeHandler() {

        WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER);
        policy.setInputBufferSize(8192);
        policy.setIdleTimeout(600000);

        return new DefaultHandshakeHandler(
                new JettyRequestUpgradeStrategy(new WebSocketServerFactory(policy)));
    }

}

或者,WebSocket XML namespace:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers>
        <websocket:mapping path="/echo" handler="echoHandler"/>
        <websocket:handshake-handler ref="handshakeHandler"/>
    </websocket:handlers>

    <bean id="handshakeHandler" class="org.springframework...DefaultHandshakeHandler">
        <constructor-arg ref="upgradeStrategy"/>
    </bean>

    <bean id="upgradeStrategy" class="org.springframework...JettyRequestUpgradeStrategy">
        <constructor-arg ref="serverFactory"/>
    </bean>

    <bean id="serverFactory" class="org.eclipse.jetty...WebSocketServerFactory">
        <constructor-arg>
            <bean class="org.eclipse.jetty...WebSocketPolicy">
                <constructor-arg value="SERVER"/>
                <property name="inputBufferSize" value="8092"/>
                <property name="idleTimeout" value="600000"/>
            </bean>
        </constructor-arg>
    </bean>

</beans>

 

2.6、配置允許的origins

自Spring Framework 4.1.5起,WebSocket和SockJS的默認行為是接受同源(same origin)請求。也可以允許所有或特定的origins列表。該檢查主要是為瀏覽器客戶端設計的。但也不會阻止其他類型的客戶端修改Origin header value (詳見RFC 6454: The Web Origin Concept)。

 

3種可能的行為是:

  • 僅允許同源請求(默認):在該模式下,當啟用SockJS時,Iframe HTTP response header X-Frame-Options 被設置成SAMEORIGIN,然后JSONP傳輸會被禁止--因其不允許檢查請求的origin。因此,啟用該模式時,不支持IE6/7。
  • 運行指定的origins列表:每個提供的allowed origin必須以 http://或https://開頭。在這種模式下,當啟用SockJS時,IFrame和JSONP都被禁止!因此不支持IE6/7/8/9。
  • 允許所有origins:設置為*即可。

允許WebSocket和SockJS的origins,可以這樣配置:

import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("http://mydomain.com");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers allowed-origins="http://mydomain.com">
        <websocket:mapping path="/myHandler" handler="myHandler" />
    </websocket:handlers>

    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

 

3、SockJS Fallback Options

如介紹中所解釋的,不是所有的瀏覽器都支持WebSocket,且可能被一些代理拒絕。這就是為什么Spring提供了fallback options -- 基於SockJS protocol (version 0.3.3)盡可能地模擬WebSocket API。

 

3.1、SockJS概覽

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-fallback-sockjs-overview

SockJS的目標是讓應用可以使用WebSocket API,但會在必要的時候回滾到non-WebSocket替代 -- 在運行時, 就是說,不需要改變應用代碼!

 

SockJS的組成:

  • 以executable narrated tests 形式定義的SockJS protocol
  • SockJS JavaScript client  -- 在瀏覽器中使用的客戶端庫。
  • SockJS服務器實現 -- 包括在Spring框架 spring-websocket 模塊中的一個。
  • 自 4.1 起,spring-websocket 也提供了一個SockJS Java client。

 

SockJS被設計用在瀏覽器中。

傳輸共分3大類別:WebSocket、HTTP Streaming、HTTP Long Polling。詳見 this blog post

 

SockJS client以發送 "GET /info" 從服務器獲取基本的信息開始。之后,它必須決定使用什么樣的傳輸。如果可以,會使用WebSocket。如果不可用,在多數瀏覽器中至少有一個HTTP Streaming選項,如果還不行,那只能使用HTTP (long) polling了!

 

所有傳輸請求都有下面的URL結構:

  • {server-id} - useful for routing requests in a cluster but not used otherwise.
  • {session-id} - correlates HTTP requests belonging to a SockJS session.
  • {transport} - indicates the transport type, e.g. "websocket", "xhr-streaming", etc.

WebSocket transport需要的是僅僅一個單一的HTTP請求來進行WebSocket握手。此后所有的消息都在那個socket上面交換。

 

HTTP transport需要更多請求。例如,Ajax/XHR streaming 依賴於一個長期運行的請求來完成服務器到客戶端的消息,額外的HTTP POST請求來完成客戶端到服務器的消息。Long polling是類似的 -- 只是 它會在每次服務器到客戶端的發送之后結束當前請求。

 

SockJS添加了最小的消息框架。例如,服務器發送字母 o (打開)開始,消息通過JSON編碼的數組發送,字母h(心跳)-- 如果如果消息流默認就是25秒,字母c(關閉)來關閉session。

 

想要學習更多,在瀏覽器中運行一個例子,然后觀察HTTP請求即可。SockJS客戶端允許固定transport列表,這樣就可以一次觀察一個transport。

SockJS客戶端還提供了debug flag,會在瀏覽器的控制台啟用幫助信息。在服務器側為org.springframework.web.socket啟用TRACE日志級別。更多詳見SockJS協議 narrated test

 

3.2、啟用SockJS

很簡單:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler").withSockJS();
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }

}

或者XML:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">

    <websocket:handlers>
        <websocket:mapping path="/myHandler" handler="myHandler"/>
        <websocket:sockjs/>
    </websocket:handlers>

    <bean id="myHandler" class="org.springframework.samples.MyHandler"/>

</beans>

上面是用於Spring MVC應用的,應該包含在DispatcherServlet配置中。然而Spring的WebSocket和SockJS支持不依賴於Spring MVC。通過SockJsHttpRequestHandler,可以很簡單地集成到其他HTTP服務環境中。

 

在瀏覽器側,應用可以使用sockjs-client (version 1.0.x)來模擬W3C WebSocket API以及與服務器通信來選擇最佳transport選項 -- 取決於運行的瀏覽器。回顧一下sockjs-client頁面和瀏覽器支持的transport類型列表。該客戶端還支持幾個配置選項,如指定包含哪些個transports。

 

3.3、IE 8/9中的HTTP Streaming:Ajax/XHR vs IFrame

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

未完待續

 

 

 

關於WebSocket:

WebSocket

 

官方文檔鏈接:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM