[英]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.