iT邦幫忙

2021 iThome 鐵人賽

DAY 30
0
Software Development

從零開始Reactive Programming- Spring系列 第 31

[Day 30] Reactive Programming - RSocket (Hello World) Part 2

前言

補充上一篇的DEMO,包含RSC的其他應用與測試的撰寫,測試是透過之前介紹過Reactor提供的StepVerifier,還沒看過的人可以先去了解一下。

RSC

就用範例中的四種模式來說明,使用linux-base的朋友就麻煩再注意一下如何跳脫,這次範例是在windows環境下使用。

Request & Response

rsc tcp://localhost:8888 --route request-response --log --debug -d "{\""name\"":\""Robert\""}"
最熟悉如同http的模式。
https://ithelp.ithome.com.tw/upload/images/20211014/20141418lkbp6ItMQz.png

Fire & Forget:

rsc tcp://localhost:8888 --route fire-and-forget --log --debug -d "{\""name\"":\""Robert\""}"
不會有回傳。
https://ithelp.ithome.com.tw/upload/images/20211014/20141418LsnoZtUhwX.png

Request Stream:

rsc tcp://localhost:8888 --stream --route greetings --log --debug -d "{\""name\"":\""Robert\""}"
透過--stream來告訴服務回傳也是stream,用來區分回傳是response還是stream。

https://ithelp.ithome.com.tw/upload/images/20211014/20141418gBssWQvpzA.png

Channels (Stream Request, Stream Response)

rsc tcp://localhost:8888 --channel --route stream-stream --log --debug -d -
透過-channel來判斷,-d後的資料透過「-(dash)」來不斷輸入資料,要注意這邊輸入的資料會直接傳送所以不需要再特別跳脫字元。
{"name":"Robert"}{"name":"Jerry"}
https://ithelp.ithome.com.tw/upload/images/20211014/20141418XFxeRrCjqA.png

Unit Test

四種互動方式的單元測試,先初始化RSocketRequester,透過builder與傳入的port來建構requester
LocalRSocketServerPort:根據文件看起來是會去抓@Value("${local.rsocket.server.port}"),推測是會自動偵測抓取本地啟動的rsocket server的port,基本上就會等同於之前定義的spring.rsocket.server.port
RSocketRequester:輕量RSocket Client,提供functional Api來建立連線、route路徑與進行物件轉換。

private static RSocketRequester requester; 
	@BeforeAll 
	public static void setupOnce(@Autowired RSocketRequester.Builder builder, 
			@LocalRSocketServerPort Integer port) { 
		requester = builder 
				.tcp("localhost", port); 
}

Request & Response

functional的測試可讀性很高,好像沒甚麼需要特別補充。

@Test
public void testRequestGetsResponse() {
 Mono<GreetingResponse> response = requester
   .route("request-response")
   .data(new GreetingRequest("Robert"))
   .retrieveMono(GreetingResponse.class);

 StepVerifier
   .create(response)
   .consumeNextWith(message -> {
    assertThat(message.getMessage()).isEqualTo("HelloRobert");
   })
   .verifyComplete();
}

FireAndForget

@Test
public void testFireAndForget() {
 Mono<Void> result = requester
   .route("fire-and-forget")
   .data(new GreetingRequest("Robert"))
   .retrieveMono(Void.class);

 StepVerifier
   .create(result)
   .verifyComplete();
}

RequestStream

RequestStreamChannel可以提前透過thenCancel()來結束。

@Test
public void testRequestStream() {
 Flux<GreetingResponse> stream = requester
   .route("greetings")
   .data(new GreetingRequest("Robert"))
   .retrieveFlux(GreetingResponse.class);

 StepVerifier
   .create(stream)
   .consumeNextWith(message -> {
    assertThat(message.getMessage()).contains("HelloRobert");
   })
   .expectNextCount(0)
   .consumeNextWith(message -> {
    assertThat(message.getMessage()).contains("HelloRobert");
   })
   .thenCancel()
   .verify();
}

Channel

@Test
public void testStreamGetsStream() {
 Flux<GreetingRequest> just = Flux
   .just(new GreetingRequest("Robert"), new GreetingRequest("Jerry"),
     new GreetingRequest("Rhys"));

 Flux<GreetingResponse> stream = requester
   .route("stream-stream")
   .data(just)
   .retrieveFlux(GreetingResponse.class);

 StepVerifier
   .create(stream)
   .consumeNextWith(message -> {
    assertThat(message.getMessage()).isEqualTo("HelloRobert");
   })
   .consumeNextWith(message -> {
    assertThat(message.getMessage()).isEqualTo("HelloJerry");
   })
   .thenCancel()
   .verify();
}

##結語
因為不想爛尾還是補了一個part 2,終於30篇結束,之後應該會整理到個人blog裡面,其實還會有最後一篇心得文,讓之後想參加鐵人賽的人參考。
補一下之前文章的source code,但沒有很完整僅供參考。

資料來源

上一篇
[Day 29] Reactive Programming - RSocket (Hello World) Part 1
下一篇
[Day 30] Reactive Programming - 感想
系列文
從零開始Reactive Programming- Spring32

1 則留言

0
juck30808
iT邦新手 3 級 ‧ 2021-10-14 11:51:34

恭喜完賽/images/emoticon/emoticon12.gif

感謝~ 你們只差一天,也恭喜妳們即將完賽!

我要留言

立即登入留言