基於Spring的WebSocket通信(一)

首先讓咱們瞭解一下幾個概念:
1、WebSocket是一種全雙工通信,它是一種底層協議,其特色包括
創建在 TCP 協議之上,服務器端的實現比較容易。
與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器。
數據格式比較輕量,性能開銷小,通訊高效。
能夠發送文本,也能夠發送二進制數據。
沒有同源限制,客戶端能夠與任意服務器通訊。
協議標識符是ws(若是加密,則爲wss),服務器網址就是 URL。javascript

2、SockJS是WebSocket的備選方案,也是底層協議。SockJS 會優先選擇 WebSocket 協議,可是若是 WebSocket協議不可用的話,他就會從以下 方案中挑選最優可行方案:
XHR streaming
XDR streaming
iFrame event source
iFrame HTML file
XHR polling
XDR polling
iFrame XHR polling
JSONP pollingjava

3、STOMP(面向消息的簡單文本協議)是基於 WebSocket(SockJS) 的上層協議,讓咱們這樣理解STOMP與WebSocket的關係:git

假設 HTTP 協議 並不存在,只能使用 TCP 套接字來 編寫 web 應用,不過幸虧,咱們有 HTTP協議,它解決了 web 瀏覽器發起請求以及 web 服務器響應請求的細節;
直接使用 WebSocket(SockJS) 就很相似於使用 TCP 套接字來編寫 web 應用;由於沒有高層協議,所以就須要咱們定義應用間所發送消息的語義,還須要確保鏈接的兩端都能遵循這些語義;
同 HTTP 在 TCP 套接字上添加 請求-響應 模型層同樣,STOMP 在 WebSocket 之上提供了一個基於 幀的線路格式層,用來定義消息語義;github

上代碼
Spring websocket提供了spring-messaging模塊,在spring繼承了Message, MessageChannel, MessageHandler等在服務器中,能處理這種消息機制的功能,spring websocket還提供了基於註解的消息處理支持。web

1、pom.xmlspring

<dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-messaging</artifactId>
         <version>${spring.version}</version>
      </dependency>

      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-websocket</artifactId>
         <version>${spring.version}</version>
      </dependency>
      
      <!-- 消息處理方面,如今不是http,沒法使用spring的HttpMessageConverter, 若是傳輸json數據的話,須要添加jackson,否則不會鏈接成功  -->
      <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.7.1-1</version>
        </dependency>

2、配置WebSocketConfigjson

@Configuration
@EnableWebSocketMessageBroker //enables WebSocket message handling, backed by a message broker.
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    static final String MESSAGE_BROKER = "/topic";
    static final String DESTINATION_PREFIX = "/app";

    // 定義消息代理,通俗一點講就是設置消息鏈接請求的各類規範信息。
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        // 客戶端訂閱地址的前綴信息,能夠爲多個,用逗號分隔
        config.enableSimpleBroker(MESSAGE_BROKER);
        // 服務端接收地址的前綴,意思就是說客戶端給服務端發消息的地址的前綴
        config.setApplicationDestinationPrefixes(DESTINATION_PREFIX);
        
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        // registers the "/gs-guide-websocket" endpoint, enabling SockJS fallback options 
        // so that alternate transports may be used if WebSocket is not available. 
        // The SockJS client will attempt to connect to "/gs-guide-websocket" and use the 
        // best transport available (websocket, xhr-streaming, xhr-polling, etc).
        registry.addEndpoint("/gs-guide-websocket").withSockJS();
        
    }

}

3、Server消息處理瀏覽器

@MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws InterruptedException {
        Thread.sleep(1000); //simulated delay
        return new Greeting("Hello, " + message.getName());
    }

4、Client消息接收發送服務器

var socket = new SockJS('/gs-guide-websocket');//注意/gs-guide-websocket就是在server這邊register的endpoint
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
       // '/topic'就是Server設定傳消息的prefix
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });

// 這裏用客戶端發送消息給服務端,也能夠是其餘地方用stomp發送消息給服務端
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));

可運行代碼在這: https://github.com/even713/Sp...websocket

參考資料: https://www.zhihu.com/questio...
https://blog.csdn.net/pacoson...

相關文章
相關標籤/搜索