RSocket 入門:Spring Boot 即發即棄

工程 | Ben Wilcock | 2020 年 3 月 16 日 | ...

閱讀時間:約 15 分鐘。

現在,一些閱讀本文的開發者使用 HTTP 已經很多年了。他們中的大多數人也知道,如果你想將 HTTP 與其他訊息傳遞模型一起使用——比如即發即棄(fire-and-forget)——有時你必須使用一些巧妙的變通方法,就像 Stackoverflow 上釋出的這個例子。這是因為 HTTP 是一種請求-響應協議(request-response protocol)。它要求傳送一個請求並接收一個響應。它沒有單向訊息的概念,也無需任何形式的響應。

RSocket 採用了不同的方法。RSocket 在 TCP 和 WebSockets 等傳輸層之上定義了一個新的協議層。這個新協議為開發者提供了更多選擇,內建支援四種不同的互動模型:

  • 請求/響應 (request/response)
  • 即發即棄 (fire-and-forget)
  • 請求/流 (request/stream)
  • 通道 (channel)

在之前的文章中,您已經瞭解瞭如何使用 RSocket 進行請求/響應通訊。在本文中,您將學習如何將即發即棄訊息傳遞新增到您的程式碼中。讓我們直接開始吧!

如果您還沒有閱讀之前關於 RSocket 的伺服器端客戶端請求-響應訊息傳遞的文章,現在是時候了!程式碼示例在 GitHub 上

步驟 1:新增伺服器端即發即棄方法

您應該還記得之前您在 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 文件中,方法簽名規則位於訊息對映部分。

步驟 2:新增客戶端即發即棄方法

您在按照上一篇文章操作時,已經在 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() 則進行訂閱並等待完成。請記住,在響應式程式碼中,沒有訂閱就不會發生任何事情。

程式碼編寫部分到此結束。現在,是時候測試它是否正常工作了。

步驟 3:構建並執行 RSocket 伺服器

開啟一個終端視窗,進入 rsocket-server 目錄。使用 Maven Wrapper 啟動伺服器,如下所示

cd rsocket-server
./mvnw clean package spring-boot:run -DskipTests=true

伺服器將在 localhost 的埠 7000 上啟動。

有關如何在 Windows 10 上執行 Linux 終端的詳細資訊,請參閱 Ubuntu 提供的這份快速指南

步驟 4:構建並執行 RSocket 客戶端

開啟第二個終端視窗,進入 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)

步驟 5:清理

您可以透過在 shell:> 提示符下輸入 exit 來停止 rsocket-client

shell:>exit

您可以透過在 rsocket-server 的終端視窗中按下 Ctrl-C 來停止該程序。

工作原理

客戶端的 .fireAndForget() 方法在呼叫 block() 方法時,使用 RSocketRequester 向伺服器傳送單個 Messageblock 方法實際上是一個“訂閱並等待”的指令。

伺服器端的 RSocketController 會檢查訊息元資料中的 route,並將訊息正確地傳遞給 .fireAndForget(Message request) 方法進行處理。一旦客戶端傳送了請求,它就可以自由地進行其他工作。當伺服器接收到請求時,它也可以繼續進行其他工作。它無需向客戶端傳送響應。

總結

在本文中,您學習瞭如何使用 Spring Boot 和 RSocket 快速構建即發即棄功能。有關 Spring RSocket 整合和訊息對映的更多資訊,請參閱 Spring RSocket 文件。在下一篇文章中,我們將介紹請求-流訊息傳遞。下篇文章見!

獲取 Spring 新聞簡報

透過 Spring 新聞簡報保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲取支援

Tanzu Spring 透過一項簡單的訂閱,即可為 OpenJDK™、Spring 和 Apache Tomcat® 提供支援和二進位制檔案。

瞭解更多

近期活動

檢視 Spring 社群的所有近期活動。

檢視全部