RSocket 入門:Spring Boot 即發即棄

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

時間:約 15 分鐘。

一些閱讀此帖的開發人員可能已經使用 HTTP 多年了。他們中的大多數人也知道,如果想要將 HTTP 與其他訊息模型(例如,即發即棄)一起使用,有時必須使用巧妙的變通方法,例如 Stackoverflow 上釋出的這個。這是因為 HTTP 是一種請求-響應協議。它要求傳送請求並接收響應。它沒有不帶任何形式響應的單向訊息的概念。

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() 方法提供資料。該訊息例項將其來源設定為 CLIENT,並將 FIRE_AND_FORGET 設定為其互動模式。

請注意,沒有 .retrieveMono() 呼叫。相反,即發即忘特有的 .send() 方法將訊息傳送到伺服器,而 .block() 訂閱並等待完成。請記住,在沒有訂閱的情況下,反應式程式碼中什麼都不會發生。

所有的編碼都完成了。現在,是時候測試它是否正常工作了。

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

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

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

伺服器在 localhost7000 埠啟動。

有關如何在 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

你可以透過在其終端視窗中按 Ctrl-C 來停止 rsocket-server 程序。

工作原理

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

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

最後思考

在這篇文章中,你學習瞭如何使用 Spring Boot 和 RSocket 快速構建一個即發即忘功能。有關 Spring RSocket 整合和訊息對映的更多資訊,請查閱 Spring RSocket 文件。在下一篇文章中,我們將介紹請求-流訊息。到時候見!

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

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

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有