訊息流

一旦 STOMP 端點暴露,Spring 應用程式就成為連線客戶端的 STOMP 代理。本節描述了伺服器端的訊息流。

spring-messaging 模組包含對訊息應用程式的基礎支援,這些支援起源於 Spring Integration,後來被提取並整合到 Spring Framework 中,以便在許多 Spring 專案和應用程式場景中廣泛使用。以下列表簡要描述了一些可用的訊息抽象。

Java 配置(即 @EnableWebSocketMessageBroker)和 XML 名稱空間配置(即 <websocket:message-broker>)都使用上述元件來組裝訊息工作流。以下圖表顯示了啟用簡單內建訊息代理時使用的元件。

message flow simple broker

上圖顯示了三個訊息通道:

  • clientInboundChannel:用於傳遞從 WebSocket 客戶端接收到的訊息。

  • clientOutboundChannel:用於向 WebSocket 客戶端傳送伺服器訊息。

  • brokerChannel:用於從伺服器端應用程式程式碼中向訊息代理傳送訊息。

下圖顯示了當配置外部代理(例如 RabbitMQ)來管理訂閱和廣播訊息時使用的元件。

message flow broker relay

前兩張圖的主要區別在於,“代理中繼”用於透過 TCP 將訊息傳遞給外部 STOMP 代理,並從代理向下傳遞訊息給訂閱的客戶端。

當從 WebSocket 連線接收到訊息時,它們被解碼為 STOMP 幀,轉換為 Spring Message 表示,併發送到 clientInboundChannel 進行進一步處理。例如,目標頭部以 /app 開頭的 STOMP 訊息可能會路由到註解控制器中的 @MessageMapping 方法,而 /topic/queue 訊息可能會直接路由到訊息代理。

處理來自客戶端的 STOMP 訊息的註解 @Controller 可以透過 brokerChannel 向訊息代理傳送訊息,代理會透過 clientOutboundChannel 將訊息廣播給匹配的訂閱者。同樣的控制器也可以響應 HTTP 請求執行相同的操作,因此客戶端可以執行 HTTP POST,然後 @PostMapping 方法可以向訊息代理傳送訊息以廣播給訂閱的客戶端。

我們可以透過一個簡單的示例來追溯訊息流。考慮以下示例,它設定了一個伺服器:

  • Java

  • Kotlin

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/portfolio");
	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		registry.setApplicationDestinationPrefixes("/app");
		registry.enableSimpleBroker("/topic");
	}
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
	override fun registerStompEndpoints(registry: StompEndpointRegistry) {
		registry.addEndpoint("/portfolio")
	}

	override fun configureMessageBroker(registry: MessageBrokerRegistry) {
		registry.setApplicationDestinationPrefixes("/app")
		registry.enableSimpleBroker("/topic")
	}
}
  • Java

  • Kotlin

@Controller
public class GreetingController {

	@MessageMapping("/greeting")
	public String handle(String greeting) {
		return "[" + getTimestamp() + ": " + greeting;
	}

	private String getTimestamp() {
		return new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date());
	}

}
@Controller
class GreetingController {
	
	@MessageMapping("/greeting")
	fun handle(greeting: String): String {
		return "[${getTimestamp()}: $greeting"
	}

	private fun getTimestamp(): String {
		return SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(Date())
	}
}

上述示例支援以下訊息流:

  1. 客戶端連線到 localhost:8080/portfolio,一旦 WebSocket 連線建立,STOMP 幀開始在其上傳輸。

  2. 客戶端傳送一個 SUBSCRIBE 幀,其目標頭部為 /topic/greeting。收到並解碼後,訊息被髮送到 clientInboundChannel,然後路由到訊息代理,訊息代理儲存客戶端訂閱。

  3. 客戶端傳送一個 SEND 幀到 /app/greeting/app 字首有助於將其路由到註解控制器。剝離 /app 字首後,目標的其餘部分 /greeting 會對映到 GreetingController 中的 @MessageMapping 方法。

  4. GreetingController 返回的值被轉換為一個 Spring Message,其有效載荷基於返回值,預設目標頭部為 /topic/greeting(從輸入目標派生,其中 /app/topic 替換)。生成的訊息被髮送到 brokerChannel 並由訊息代理處理。

  5. 訊息代理找到所有匹配的訂閱者,並透過 clientOutboundChannel 向每個訂閱者傳送一個 MESSAGE 幀,訊息從那裡被編碼為 STOMP 幀並在 WebSocket 連線上傳輸。

下一節將提供有關注解方法的更多詳細資訊,包括支援的引數型別和返回值。

© . This site is unofficial and not affiliated with VMware.