spring 4.x mvc整合websocket以及sockjs完全參考指南(含nginx/https支援)__js

來源:互聯網
上載者:User

之所以sockjs會存在,說得不好聽點,就是因為微軟是個流氓,現在使用windows 7的系統仍然有近半,而windows 7預設內建的是ie 8,有些會自動更新到ie 9,但是大部分非IT使用者其實都不願意或者不會升級(通常我們做IT的認為很簡單的事情,在其他行業的人來看,那就是天書,不要覺得不可能,現實已如此)。

現在言歸正傳,這裡完整的講下在spring 4.x整合sockjs,以及運行在tomcat 7下時的一些額外注意事項。

spring websocket依賴jar:

        <dependency>            <groupId>javax.websocket</groupId>            <artifactId>javax.websocket-api</artifactId>            <version>1.1</version>            <scope>provided</scope> <!-- 注意,scope必須為provided,否則runtime會衝突,如果使用tomcat 8,還需要將TOMCAT_HOME/lib下的javax.websocket-api.jar一併刪除 -->        </dependency>        <dependency>            <groupId>org.springframework</groupId>            <artifactId>spring-websocket</artifactId>            <version>4.2.8.RELEASE</version>        </dependency>

除非使用STOMP協議,否則不需要依賴spring-messaging。

spring通過兩種模式支援websocket,一種是通過原生websocket規範的ws://協議訪問(個人認為如果確定只用標準websocket訪問,還不如tomcat升級到8.x(tomcat 8原生支援JSR 356註解),spring的大量封裝畢竟增加了不少額外負載);另一種則是通過sockjs(也就是js)訪問,兩者目前暫時無法做到相容。

先完整說明第一種:

1、搭建spring mvc環境,這一點假設讀者已知;

2、pom.xml中引入上面兩個jar包;

3、spring支援websocket總共分為四個小步驟,handler、interceptor、config、web.xml,基本上可以認為spring mvc的翻版。

3.1、建立WebSocketHandler,spring支援兩種方式,一種是實現org.springframework.web.socket.WebSocketHandler介面,另外一種則是繼承TextWebSocketHandler或BinaryWebSocketHandler(現在大部分模板式架構或者外掛程式通常都是在提供了API的基礎上提供了抽象類別,把一些能統一的工作提前預置了,以便應用只需要關心業務,我們自己公司的中介軟體架構很多也是用這個模式實現了)。

/** *  */package com.ld.net.spider.demo.ws;/** * @author zhjh256@163.com * {@link} http://www.cnblogs.com/zhjh256 */import org.springframework.web.socket.CloseStatus;import org.springframework.web.socket.TextMessage;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.WebSocketMessage;import org.springframework.web.socket.WebSocketSession;public class DemoWSHandler implements WebSocketHandler {        @Override      public void afterConnectionEstablished(WebSocketSession session) throws Exception {          System.out.println("connect to the websocket success......");          session.sendMessage(new TextMessage("Server:connected OK!"));      }        @Override      public void handleMessage(WebSocketSession wss, WebSocketMessage<?> wsm) throws Exception {          TextMessage returnMessage = new TextMessage(wsm.getPayload()                  + " received at server");          System.out.println(wss.getHandshakeHeaders().getFirst("Cookie"));          wss.sendMessage(returnMessage);      }        @Override    public void handleTransportError(WebSocketSession wss, Throwable thrwbl) throws Exception {          if(wss.isOpen()){              wss.close();          }         System.out.println("websocket connection closed......");      }        @Override      public void afterConnectionClosed(WebSocketSession wss, CloseStatus cs) throws Exception {          System.out.println("websocket connection closed......");      }        @Override      public boolean supportsPartialMessages() {          return false;      }}

3.2、建立攔截器

/** *  */package com.ld.net.spider.demo.ws;import java.util.Map;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;/** * @author zhjh256@163.com  * {@link} http://www.cnblogs.com/zhjh256 */public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {    @Override    public boolean beforeHandshake(ServerHttpRequest request,            ServerHttpResponse response, WebSocketHandler wsHandler,            Map<String, Object> attributes) throws Exception {        // 解決The extension [x-webkit-deflate-frame] is not supported問題        if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {            request.getHeaders().set("Sec-WebSocket-Extensions",                    "permessage-deflate");        }        System.out.println("Before Handshake");        return super.beforeHandshake(request, response, wsHandler, attributes);    }    @Override    public void afterHandshake(ServerHttpRequest request,            ServerHttpResponse response, WebSocketHandler wsHandler,            Exception ex) {        System.out.println("After Handshake");        super.afterHandshake(request, response, wsHandler, ex);    }}

3.3、bean配置

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:mongo="http://www.springframework.org/schema/data/mongo"xmlns:cache="http://www.springframework.org/schema/cache"xmlns:c="http://www.springframework.org/schema/c"xmlns:amq="http://activemq.apache.org/schema/core"xmlns:websocket="http://www.springframework.org/schema/websocket"xmlns:jms="http://www.springframework.org/schema/jms"xmlns:util="http://www.springframework.org/schema/util"   xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/websockethttp://www.springframework.org/schema/websocket/spring-websocket.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/data/mongo       http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd   http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/cachehttp://www.springframework.org/schema/cache/spring-cache.xsdhttp://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsdhttp://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms.xsdhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd">    <websocket:handlers allowed-origins="*">        <websocket:mapping path="/springws/websocket.ws" handler="demoWSHandler"/>         <websocket:handshake-interceptors>            <bean class="com.ld.net.spider.demo.ws.HandshakeInterceptor"/>        </websocket:handshake-interceptors>    </websocket:handlers>    <bean id="demoWSHandler" class="com.ld.net.spider.demo.ws.DemoWSHandler"/>

上述需要注意的是,1、spring javadoc的說明是預設情況下,允許所有來源訪問,但我們跑下來發現不配置allowed-origins的話總是報403錯誤。

2、sockjs是不允許有尾碼的,否則將無法匹配,後面會專門講到。

3.4、web.xml配置

在web.xml中增加*.ws映射即可(如果原來不是/*的話),如下:

    <servlet-mapping>        <servlet-name>springMVC</servlet-name>        <url-pattern>*.ws</url-pattern>    </servlet-mapping>

上述配置完成之後,就可以通過標準的websocket介面進行訪問了,如下所示。

4、websocket用戶端

<!DOCTYPE html>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.