領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多閱讀時間:約 15 分鐘。
現在,一些閱讀本文的開發者使用 HTTP 已經很多年了。他們中的大多數人也知道,如果你想將 HTTP 與其他訊息傳遞模型一起使用——比如即發即棄(fire-and-forget)——有時你必須使用一些巧妙的變通方法,就像 Stackoverflow 上釋出的這個例子。這是因為 HTTP 是一種請求-響應協議(request-response protocol)。它要求傳送一個請求並接收一個響應。它沒有單向訊息的概念,也無需任何形式的響應。
RSocket 採用了不同的方法。RSocket 在 TCP 和 WebSockets 等傳輸層之上定義了一個新的協議層。這個新協議為開發者提供了更多選擇,內建支援四種不同的互動模型:
在之前的文章中,您已經瞭解瞭如何使用 RSocket 進行請求/響應通訊。在本文中,您將學習如何將即發即棄訊息傳遞新增到您的程式碼中。讓我們直接開始吧!
如果您還沒有閱讀之前關於 RSocket 的伺服器端和客戶端請求-響應訊息傳遞的文章,現在是時候了!程式碼示例在 GitHub 上。
您應該還記得之前您在 rsocket-server
專案中使用的 RSocketController
@Slf4j
@Controller
public class RSocketController {
// code goes here
}
RSocketController
是處理請求-響應訊息傳遞的伺服器端類。它的 .requestResponse()
方法接受一個 Message
物件作為引數,並返回一個 Message
物件作為響應。正是這種“一個輸入物件,一個輸出物件”的方法簽名使得該方法成為請求-響應方法。
要向伺服器新增即發即棄功能,您必須新增一個具有不同簽名的方法。.fireAndForget()
方法應接受單個 Message
引數,但這次應返回 void
,如下所示...
@MessageMapping("fire-and-forget")
public void fireAndForget(Message request) {
log.info("Received fire-and-forget request: {}", request);
}
您仍然必須在方法上使用 @MessageMapping
註解,但這次您必須為 路由 對映指定一個不同的名稱。在上面的程式碼中,我使用了名稱 "fire-and-forget"。
在 Spring RSocket 文件中,方法簽名規則位於訊息對映部分。
您在按照上一篇文章操作時,已經在 rsocket-client
專案中構建了 RSocketShellClient
@Slf4j
@ShellComponent
public class RSocketShellClient {
// code goes here
}
RSocketShellClient 使用 .requestResponse()
方法,透過在類建構函式中建立的 RSocketRequester
向 RSocket 伺服器傳送單個請求。
要將即發即棄功能新增到您的客戶端,請像這樣向 RSocketShellClient
新增一個新的 .fireAndForget()
方法
@ShellMethod("Send one request. No response will be returned.")
public void fireAndForget() throws InterruptedException {
log.info("\nFire-And-Forget. Sending one request. Expect no response (check server log)...");
this.rsocketRequester
.route("fire-and-forget")
.data(new Message(CLIENT, FIRE_AND_FORGET))
.send()
.block();
}
讓我們更詳細地檢查此方法中的程式碼
rsocketRequester
上的 .route()
設定為 "fire-and-forget"
。這個路由名稱與 RSocketController
中即發即棄方法上的 @MessageMapping
註解匹配。
一個新的 Message
例項為 .data()
方法提供資料。訊息例項的 origin 設定為 CLIENT
,其互動模式設定為 FIRE_AND_FORGET
。
注意,這裡沒有呼叫 .retrieveMono()
。相反,即發即棄特定的 .send()
方法將訊息傳送到伺服器,而 .block()
則進行訂閱並等待完成。請記住,在響應式程式碼中,沒有訂閱就不會發生任何事情。
程式碼編寫部分到此結束。現在,是時候測試它是否正常工作了。
開啟一個終端視窗,進入 rsocket-server
目錄。使用 Maven Wrapper 啟動伺服器,如下所示
cd rsocket-server
./mvnw clean package spring-boot:run -DskipTests=true
伺服器將在 localhost
的埠 7000
上啟動。
有關如何在 Windows 10 上執行 Linux 終端的詳細資訊,請參閱 Ubuntu 提供的這份快速指南。
開啟第二個終端視窗,進入 rsocket-client
目錄。然後,按照以下步驟構建並執行客戶端應用程式
cd rsocket-client
./mvnw clean package spring-boot:run -DskipTests=true
客戶端執行後,Spring Shell 會為您呈現一個新的提示符
shell:>
您可以在提示符下輸入 fire-and-forget
將您的即發即棄訊息傳送到伺服器。
shell:>fire-and-forget
2020-02-03 14:54:14.028 INFO 2929 --- [ main] io.pivotal.rsocketclient.RSocketClient :
Fire-And-Forget. Sending one request. Expect no response (check server)...
客戶端不會列印任何響應,但如果您切換到伺服器的終端視窗,您會注意到即發即棄訊息的接收已成功記錄到控制檯。
2020-02-03 14:54:14.129 INFO 2061 --- [or-http-epoll-2] io.pivotal.rsocketserver.RSocketServer : Received fire-and-forget request: Message(origin=Client, interaction=Fire-And-Forget, index=0, created=1580741654)
您可以透過在 shell:>
提示符下輸入 exit 來停止 rsocket-client
。
shell:>exit
您可以透過在 rsocket-server
的終端視窗中按下 Ctrl-C
來停止該程序。
客戶端的 .fireAndForget()
方法在呼叫 block()
方法時,使用 RSocketRequester
向伺服器傳送單個 Message
。block
方法實際上是一個“訂閱並等待”的指令。
伺服器端的 RSocketController
會檢查訊息元資料中的 route
,並將訊息正確地傳遞給 .fireAndForget(Message request)
方法進行處理。一旦客戶端傳送了請求,它就可以自由地進行其他工作。當伺服器接收到請求時,它也可以繼續進行其他工作。它無需向客戶端傳送響應。
在本文中,您學習瞭如何使用 Spring Boot 和 RSocket 快速構建即發即棄功能。有關 Spring RSocket 整合和訊息對映的更多資訊,請參閱 Spring RSocket 文件。在下一篇文章中,我們將介紹請求-流訊息傳遞。下篇文章見!