學習WebSocket(一):Spring WebSocket的簡單使用

Gin.p發表於2015-08-16

1、什麼是websocket?

  WebSocket協議定義了一種web應用的新功能,它實現了伺服器端和客戶端的全雙工通訊。全雙工通訊即通訊的雙方可以同時傳送和接收資訊 的資訊互動方式。它是繼Java applets, XMLHttpRequest, Adobe Flash, ActiveXObject等使web應用更具互動性的新技術。

  在實現連線過程中,瀏覽器和伺服器通過TCP三次握手建立連線。 如果和伺服器連線成功後,瀏覽器通過HTTP傳送握手請求,如果伺服器同意握手連線,客戶端和服務端之後就能互相之間傳送資訊。HTTP只用於開始的握手,一旦成功建立握手連線,HTTP不會參與資料傳輸,使用TCP連線來傳輸資料。

2、以往和伺服器互動的幾種方式

  輪詢

  長輪詢就是客戶端按照一個固定的時間定期向伺服器傳送請求,通常這個時間間隔的長度受到服務端的更新頻率和客戶端處理更新資料時間的影響。這種方式缺點很明顯,就是瀏覽器要不斷髮請求到伺服器以獲取最新資訊,造成伺服器壓力過大,佔用寬頻資源。

    使用streaming AJAX

  streaming ajax是一種通過ajax實現的長連線維持機制。主要目的就是在資料傳輸過程中對返回的資料進行讀取,並且不會關閉連線。

  iframe方式

  iframe可以在頁面中巢狀一個子頁面,通過將iframe的src指向一個長連線的請求地址,服務端就能不斷往客戶端傳輸資料。

3、什麼時候用websocket?

  最適合websocket的web應用的就是那些客戶端和伺服器端需要高頻繁、低延遲交換資訊的應用。

4、如何使用websocket?

  Spring提供了一個是適應於各種websocket引擎的websocket api,例如是Tomcat (7.0.47+)和GlassFish (4.0+),也適應於支援原生websocket的Jetty (9.0+)。而不同的瀏覽器對websocket的支援程度也有所不同,如果瀏覽器websocket不支援,那麼可以用SocketJs代替websocket。

  建立和配置WebSocketHandler

  WebSocketHandler用於處理websocket的訊息。

public class MyHandler extends TextWebSocketHandler {

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

建立和配置HandshakeInterceptor

HandshakeInterceptor用於處理握手前後的預處理工作。

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
        System.out.println("After Handshake");
        super.afterHandshake(request, response, wsHandler, ex);
    }

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,Map<String, Object> attributes) throws Exception {
        System.out.println("Before Handshake");
     return super.beforeHandshake(request, response, wsHandler, attributes); } }

同時配置spring-websocket.xml

<?xml version="1.0" encoding="UTF-8"?>
<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 handler="myHandler" path="/myHandler"/>
        <websocket:handshake-interceptors>
            <bean class="org.springframework.samples.HandshakeInterceptor"></bean>
        </websocket:handshake-interceptors>
    </websocket:handlers> 
    <!--相容低版本瀏覽器-->    
    <websocket:handlers>    
        <websocket:mapping handler="myHandler" path="/js/myHandler"/>    
        <websocket:handshake-interceptors>
            <bean class="org.springframework.samples.HandshakeInterceptor"></bean>
        </websocket:handshake-interceptors>
        <websocket:sockjs />
    </websocket:handlers>
    
    <bean id="myHandler" class="org.springframework.samples.MyHandler"></bean>
           
</beans>

在頁面上新增JavaScript

<script type="text/javascript" src="js/sockjs.min.js"></script>
<script type="text/javascript">
  //websocket-demo是project name
    var sock=null;
    if (window['WebSocket']) {
        sock= new WebSocket('ws://' + window.location.host+'/websocket-demo/myHandler');
    }
    else
        sock= new SockJS('/websocket-demo/js/myHandler');//相容低版本瀏覽器
    sock.onopen = function() {
        console.log('Opening');
        sayHello();
    };
    sock.onmessage = function(e) {
        alert('Received message: '+ e.data);
    };
    sock.onclose = function() {
        console.log('Closing');
    };
    function sayHello() {
        console.log('Sending Hello!');
        sock.send("Hello!");
    }
</script>

如果要相容低版本瀏覽器,還要在web.xml新增

<async-supported>true</async-supported>

需要注意的地方:

1、應用伺服器的版本,如果版本過低是不支援websocket的

2、JavaScript的websocket的url應該和spring-websocket.xml的<websocket:mapping path="">一致

3、要相容低版本瀏覽器,要使用web3.0,還有必須在一個請求涉及的所有Servlet及Filter中都宣告asyncSupported=true。

下載:websocket-demo

相關文章