首先讓咱們瞭解一下幾個概念:
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...