WebSocket是html5帶來的一項重大的特性,使得瀏覽器與服務端之間真正長連接交互成為了可能,這篇文章會帶領大家窺探一下Spring 對WebSocket的支持及使用。
基礎環境
快速搭建Spring框架,我們使用Spring boot,這里先不討論SpringBoot,只知道它是一個“快速搭建Spring項目的一站式解決方案”就OK了。
要使用Spring的WebSocket功能,我們需要添加依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
這樣就輕松開啟了WebSocket基礎功能。
相關配置
下面我們來配置WebSocket。
首先新增一個WebSocketConfig類,定義全局的配置信息,使用JavaConfig的形式:
WebSocketConfig.java
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/socket").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker("/topic"); registry.setApplicationDestinationPrefixes("/app"); } }
相關說明:
-
registerStompEndpoints(StompEndpointRegistry registry)
這個方法的作用是添加一個服務端點,來接收客戶端的連接。
-
registry.addEndpoint("/socket")
表示添加了一個/socket
端點,客戶端就可以通過這個端點來進行連接。 -
withSockJS()
的作用是開啟SockJS支持,
-
configureMessageBroker(MessageBrokerRegistry config)
這個方法的作用是定義消息代理,通俗一點講就是設置消息連接請求的各種規范信息。
-
registry.enableSimpleBroker("/topic")
表示客戶端訂閱地址的前綴信息,也就是客戶端接收服務端消息的地址的前綴信息(比較繞,看完整個例子,大概就能明白了) -
registry.setApplicationDestinationPrefixes("/app")
指服務端接收地址的前綴,意思就是說客戶端給服務端發消息的地址的前綴
上面兩個方法定義的信息其實是相反的,一個定義了客戶端接收的地址前綴,一個定義了客戶端發送地址的前綴
到目前為止,整個框架的配置信息已經完成,下面我們來寫一個發送公告的例子,展示一下WebSocket的魅力!
編寫后台業務
有了上述的基本配置信息,我們就可以編寫基本功能了。這里先簡單說明兩個知識點:
- MessageMapping
Spring對於WebSocket封裝的特別簡單,提供了一個@MessageMapping
注解,功能類似@RequestMapping
,它是存在於Controller
中的,定義一個消息的基本請求,功能也跟@RequestMapping
類似,包括支持通配符``的url定義等等,詳細用法參見Annotation Message Handling - SimpMessagingTemplate
SimpMessagingTemplate
是Spring-WebSocket內置的一個消息發送工具,可以將消息發送到指定的客戶端。
下面我們來實現:
新建一個GreetingController
,
@Controller public class GreetingController { @Resource private SimpMessagingTemplate simpMessagingTemplate; @RequestMapping("/helloSocket") public String index(){ return "/hello/index"; } @MessageMapping("/change-notice") public void greeting(String value){ this.simpMessagingTemplate.convertAndSend("/topic/notice", value); } }
相關說明:
- index()
指定了一個頁面,用來實現WebSocket客戶端發送公告功能,使用的是@RequestMapping
,所以接收的是http請求,進行頁面跳轉。 - greeting(String value)
這個方法是接收客戶端發送功公告的WebSocket請求,使用的是@MessageMapping
。 -
this.simpMessagingTemplate.convertAndSend("/topic/notice", value)
這個方法官方給出的解釋是Convert the given Object to serialized form, possibly using a MessageConverter, wrap it as a message and send it to the given destination.
意思就是“將給定的對象進行序列化,使用‘MessageConverter’進行包裝轉化成一條消息,發送到指定的目標”,通俗點講就是我們使用這個方法進行消息的轉發發送!
前面我們全局配置中指定了服務端接收的連接以 app
大頭,所以客戶端發送公告的請求連接應該是/app/change-notice
。
服務端代碼就這么簡單,跟寫SpringMVC類似,同樣上面的geeting(String value)
方法我們還可以使用另一個注解@SendTo
換成另一種寫法。
@MessageMapping("/change-notice") @SendTo("/topic/notice") public String greeting(String value) { return value; }
相關說明:
改進后的代碼更簡單,着重理解一下@SendTo
。
-
@SendTo
定義了消息的目的地。結合例子解釋就是“接收/app/change-notice
發來的value,然后將value轉發到/topic/notice
客戶端。 -
/topic/notice
是客戶端發起連接后,訂閱服務端消息時指定的一個地址,用於接收服務端的返回,后面我們在寫客戶端代碼的時候會看見。
到目前為止,服務端代碼Coding完畢!下一篇文章我們來寫客戶端功能。