簡體   English   中英

如何在不使用 Java 中的 Spring 庫的情況下創建 RSocket 請求端點?

[英]How to create RSocket request endpoints without using Spring Library in Java?

我想使用計划 Java RSocket SDK 創建 RSocket 請求端點,而不使用 Spring 框架。 我能夠在以下代碼片段的幫助下創建示例請求。 這僅適用於請求tcp://localhost:7000 但我想創建與此類似的不同端點。

public class ServerExample {
    public static void main(String[] args) {
        Hooks.onErrorDropped(e -> {});
        RSocket handler = new RSocket() {
            @Override
            public Mono<Payload> requestResponse(Payload payload) {
                System.out.println("RequestResponse: " + payload.getDataUtf8());
                return Mono.just(payload);
            }

            @Override
            public Flux<Payload> requestStream(Payload payload) {
                System.out.println("RequestStream: " + payload.getDataUtf8());
                return Flux.just("First", "Second").map(DefaultPayload::create);
            }

            @Override
            public Mono<Void> fireAndForget(Payload payload) {
                System.out.println("FireAndForget: " + payload.getDataUtf8());
                return Mono.empty();
            }
        };
        RSocketServer.create(SocketAcceptor.with(handler))
                .bindNow(TcpServerTransport.create("localhost", 7000))
                .onClose()
                .doOnSubscribe(subscription -> System.out.println("RSocket Server listen on tcp://localhost:7000"))
                .block();
    }
}

您可以利用RSocket協議定義的元數據,更明確地說是Routing擴展元數據

您的服務器實現將更新為根據特定請求路由元數據值動態切換響應者進行響應:

public class ServerExample {

    public static void main(String[] args) {
        Hooks.onErrorDropped(e -> {
        });
        final String userRoute = "/user"; // this defines one of the route values
        final String organizationRoute = "/organization"; // this defines another route value
        RSocket handler = new RSocket() {
            @Override
            public Mono<Payload> requestResponse(Payload payload) {
                final String route;
                if (payload.hasMetadata()) { // check if you have compulsory metadata
                    route = new RoutingMetadata(payload.metadata().slice()).iterator().next(); // read the routing metadata value
                } else {
                    throw new IllegalStateException();
                }
                switch (route) { // based on the route value, you can respond accordingly
                    case userRoute: {
                        System.out.println("RequestResponse for route " + route + ": " + payload.getDataUtf8());
                        return Mono.just(DefaultPayload.create("Echo for: User"));
                    }
                    case organizationRoute: {
                        System.out.println("RequestResponse for route " + route + ": " + payload.getDataUtf8());
                        return Mono.just(DefaultPayload.create("Echo for: Organization"));
                    }
                    default: return Mono.just(DefaultPayload.create("Unsupported route"));
                }
            }

            @Override
            public Flux<Payload> requestStream(Payload payload) {
                System.out.println("RequestStream: " + payload.getDataUtf8());
                return Flux.just("First", "Second").map(DefaultPayload::create);
            }

            @Override
            public Mono<Void> fireAndForget(Payload payload) {
                System.out.println("FireAndForget: " + payload.getDataUtf8());
                return Mono.empty();
            }
        };
        RSocketServer.create(SocketAcceptor.with(handler))
                .bindNow(TcpServerTransport.create("localhost", 7000))
                .onClose()
                .doOnSubscribe(subscription -> System.out.println("RSocket Server listen on tcp://localhost:7000"))
                .block();
    }
}

在客戶端實現中,您需要提供編碼后的routing元數據,如下所示:

public class ClientExample {

    public static void main(String[] args) {
        Mono<RSocket> source =
                RSocketConnector.create()
                        .reconnect(Retry.backoff(50, Duration.ofMillis(500)))
                        .connect(TcpClientTransport.create("localhost", 7000));
        // User route request
        ByteBuf userRouteMetadata = TaggingMetadataCodec.createRoutingMetadata(
                        UnpooledByteBufAllocator.DEFAULT,
                        Collections.singletonList("/user")
                )
                .getContent();

        RSocketClient.from(source)
                .requestResponse(Mono.just(DefaultPayload.create(Unpooled.buffer().writeBytes("Requesting user resource".getBytes()), userRouteMetadata)))
                .doOnSubscribe(s -> logger.info("Executing Request"))
                .doOnNext(
                        d -> {
                            logger.info("Received response data {}", d.getDataUtf8());
                            d.release();
                        })
                .repeat(5)
                .blockLast();

        // Organization route request
        ByteBuf organizationRouteMetadata = TaggingMetadataCodec.createRoutingMetadata(
                        UnpooledByteBufAllocator.DEFAULT,
                        Collections.singletonList("/organization")
                )
                .getContent();
        RSocketClient.from(source)
                .requestResponse(Mono.just(DefaultPayload.create(Unpooled.buffer().writeBytes("Requesting organization resource".getBytes()), organizationRouteMetadata)))
                .doOnSubscribe(s -> logger.info("Executing Request"))
                .doOnNext(
                        d -> {
                            logger.info("Received response data {}", d.getDataUtf8());
                            d.release();
                        })
                .repeat(5)
                .blockLast();
    }
}

正如您從該示例中注意到的那樣,實現相當復雜,並且隨着您的實現收集更多需求,其復雜性也會增加。 必須特別注意正確的ByteBuf操作,因為這會嚴重損害您的應用程序 memory 並且您可以通過保留引用輕松泄漏其中之一,因此需要依賴可靠的實現,如 Spring 提供的實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM