SpringBoot 2.2でRSocket
SpringBoot 2.2でRSocketを試してみました。
org.springframework.messaging.MessageDeliveryException: No handler for destination ''
というのが出て最初はうまく動かなかったのですが、何とか動きました。
構成
ユーザからのリクエストを受け付けるRESTのエンドポイントがあり、バックエンドをRSocketで通信している風です。
clientという名前が分かりにくいですね。。
[user] -- http/rest --> [client] -- tcp/rsocket --> [server]
Server
ざっくりこんな感じです。
@Controller public class GreetingRSocketController { @MessageMapping("hello") public Mono<GreetingData> hello(GreetingRequest request) { return Mono.just(new GreetingData("hello " + request.getWord())); } @MessageExceptionHandler public Mono<GreetingData> handleException(Exception e) { return Mono.just(GreetingData.fromException(e)); } } @Data @AllArgsConstructor @NoArgsConstructor public class GreetingData { private String word; public static GreetingData fromException(Exception e) { return new GreetingData(e.getMessage()); } } @Data @AllArgsConstructor @NoArgsConstructor public class GreetingRequest { private String word; }
Client
こちらもざっくりと。
Serverと重複するGreetingDataとGreetingRequestは省略です。
@RestController public class GreetingRestController { private final RSocketRequester requester; @Autowired public GreetingRestController(RSocketRequester requester) { this.requester = requester; } @GetMapping("/hello/{word}") public Publisher<GreetingData> current(@PathVariable("word") String word) { return requester.route("hello").data(new GreetingRequest(word)).retrieveMono(GreetingData.class); } } @Configuration public class ClientConfiguration { @Bean public RSocket rsocket() { return RSocketFactory.connect() .dataMimeType(MimeTypeUtils.APPLICATION_JSON_VALUE) .metadataMimeType(WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()) .frameDecoder(PayloadDecoder.ZERO_COPY) .transport(TcpClientTransport.create(7000)) .start().block(); } @Bean public RSocketRequester rsocketRequester(RSocketStrategies rsocketStrategies) { return RSocketRequester.wrap(rsocket(), MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_ROUTING.getString()), rsocketStrategies); } }
最初に書いた例外は、metaDataTimeTypeの設定不備によるものでした。