首頁  >  文章  >  web前端  >  spring WebSocket的詳細介紹

spring WebSocket的詳細介紹

零下一度
零下一度原創
2017-07-03 15:18:281804瀏覽

場景

websocket是Html5新增加特性之一,目的是瀏覽器與服務端建立全雙工的通信方式,解決http請求-響應帶來過多的資源消耗,同時對特殊場景應用提供了全新的實現方式,例如聊天、股票交易、遊戲等對對即時性要求較高的產業領域。

背景

在瀏覽器中透過http僅能實現單向的通訊,comet可以一定程度上模擬雙向通訊,但效率較低,並需要伺服器有較好的支援; flash中的socket和xmlsocket可以實現真正的雙向通信,通過flex ajax bridge,可以在javascript中使用這兩項功能. 可以預見,如果websocket一旦在瀏覽器中得到實現,將會替代上面兩項技術,得到廣泛的使用.面對這種狀況,HTML5定義了WebSocket協議,能更好的節省伺服器資源和頻寬並達到即時通訊。目前各大主流瀏覽器都支援websocket,IE瀏覽器要IE10+

一、POM依賴

POM依賴,spring4.1.4.RELEASE,spring

<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.0</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
二、WebSocket入口
@Configuration
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //允许连接的域,只能以http或https开头
        String[] allowsOrigins = {"http://www.xxx.com"};
        
       //WebIM WebSocket通道
        registry.addHandler(chatWebSocketHandler(),"/           webSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor());
        registry.addHandler(chatWebSocketHandler(), "/sockjs/w          ebSocketIMServer").setAllowedOrigins(allowsOrigins).addInterceptors(myInterceptor()).withSockJS();
    }
    @Bean
    public ChatWebSocketHandler chatWebSocketHandler() {
        return new ChatWebSocketHandler();
    }
    @Bean
    public WebSocketHandshakeInterceptor myInterceptor(){
        return new WebSocketHandshakeInterceptor();
    }
}

    實現WebSocketConfigurer接口,重寫registerWebSocketHandlers方法,這是一個核心實現方法,配置websocket入口,允許訪問的域、Handler、SockJs支援和攔截器。
  1. registry.addHandler註冊和路由的功能,當客戶端發起websocket連接,把/path交給對應的handler處理,而不實現具體的業務邏輯,可以理解為收集和任務分發中心。
  2. setAllowedOrigins(String[] domains),允許指定的域名或IP(含端口號)建立長連接,如果只允許自家域名訪問,這裡輕鬆設置。如果不限時使用"*"號,如果指定了域名,則必須以http或https開頭。
  3. addInterceptors,顧名思義就是為handler添加攔截器,可以在呼叫handler前後加入我們自己的邏輯程式碼。
  4. spring websocket也支援STOMP協議,下回再分享。
  5. 三、攔截器實作
public class WebSocketHandshakeInterceptor implements HandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object
                > attributes) throws Exception {
        if (request instanceof ServletServerHttpRequest) {
            attributes.put("username",userName);
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

    }
}

beforeHandshake,在呼叫handler前處理方法。常用在註冊用戶訊息,綁定WebSocketSession,在handler裡根據用戶資訊取得WebSocketSession

發送訊息

四、Handler處理類

public class ChatWebSocketHandler extends TextWebSocketHandler{
    
    private final static List<WebSocketSession> sessions = Collections.synchronizedList(new ArrayList<WebSocketSession>());
    //接收文本消息,并发送出去
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        chatTextMessageHandler(message.getPayload());
        super.handleTextMessage(session, message);
    }
    //连接建立后处理
    @SuppressWarnings("unchecked")
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.debug("connect to the websocket chat success......");
        sessions.add(session);
        //处理离线消息
    }
    //抛出异常时处理
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if(session.isOpen()){
            session.close();
        }
        logger.debug("websocket chat connection closed......");
        sessions.remove(session);
    }
    //连接关闭后处理
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("websocket chat connection closed......");
        sessions.remove(session);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

五、客戶端連接

var host = window.location.host;
var websocket;
if ('WebSocket' in window) {
    websocket = new ReconnectingWebSocket("ws://"
        + host + "/webSocketIMServer", null, {debug:true, maxReconnectAttempts:4});
} else if ('MozWebSocket' in window) {
    websocket = new MozWebSocket("ws://" + host
        + "/webSocketIMServer");
} else {
    websocket = new SockJS("http://" + host
            + "/sockjs/webSocketIMServer");
}
websocket.onopen = function(evnt) {
    console.log("websocket连接上");
};
websocket.onmessage = function(evnt) {
    messageHandler(evnt.data);
};
websocket.onerror = function(evnt) {
    console.log("websocket错误");
};
websocket.onclose = function(evnt) {
    console.log("websocket关闭");
}

這裡用到了ReconnectingWebSocket.js,對瀏覽器自帶websocket添加了擴展,例如重連,連接超時時間,失敗重連間隔,嘗試連接最大次數等。

專案首頁:ReconnectingWebSocket

以上是spring WebSocket的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn