微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

RSocket Net 客户端请求流路由元数据到 Spring Boot @MessageMapping 路由

如何解决RSocket Net 客户端请求流路由元数据到 Spring Boot @MessageMapping 路由

rsocket routing metadata using RSocket-Java for Spring Rsocket Server 类似,但对于 RSocket Net Client,我们使用 Spring Boot @MessageMapping 用于端口 7000 上的 websocket 端点路由,该路由根据路由返回 webfluxes。例如:

@MessageMapping(value = "helloWorld")
public Flux<String> getFluxSocket() {
    log.traceEntry();
    log.info("In hello world");
    
    return Flux.just("{\"Hello\":\"World\"}");
}

当 Spring Boot 服务器在本地运行时,要获得此通量,您可以使用 rsc client

java -jar rsc.jar --debug --request --route helloWorld ws://localhost:7000

或用于流

java -jar rsc.jar --debug --stream --route myStream ws://localhost:7000

要在 C# Net 中以编程方式执行此操作,它表示 here RSocket Net 尚不支持请求路由,但可以使用元数据负载。有没有人得到过这样的网络?

CompositeByteBuf Metadata = ByteBufAllocator.DEFAULT.compositeBuffer();
RoutingMetadata routingMetadata = TaggingMetadataCodec.createRoutingMetadata(ByteBufAllocator.DEFAULT,List.of("/route"));
CompositeMetadataCodec.encodeAndAddMetadata(Metadata,ByteBufAllocator.DEFAULT,WellKNownMimeType.MESSAGE_RSOCKET_ROUTING,routingMetadata.getContent());

谢谢

解决方法

您可以实现路由元数据,直到 .NET 库正式支持路由/复合元数据。 如果不需要发送路由元数据以外的任何元数据,则不需要创建复合元数据。仅发送路由元数据非常简单。

从规范中可以看出,只需将路由名称的长度添加到第一个字节即可。 https://github.com/rsocket/rsocket/blob/master/Extensions/Routing.md

我对 .NET 一无所知,所以我将向您展示如何用 Java 和 JavaScript 来实现它。仅供参考。

https://github.com/making/demo-rsocket/blob/master/vanilla-rsocket-client/src/main/java/com/example/vanillarsocketclient/VanillaRsocketClientApplication.java

static ByteBuffer routingMetadata(String tag) {
    final byte[] bytes = tag.getBytes(StandardCharsets.UTF_8);
    final ByteBuffer buffer = ByteBuffer.allocate(1 + bytes.length);
    buffer.put((byte) bytes.length);
    buffer.put(bytes);
    buffer.flip();
    return buffer;
}

https://github.com/making/demo-rsocket-jsug/blob/master/frontend/vanilla/src/index.js

const routingMetadata = (route) => {
    return String.fromCharCode(route.length) + route;
};
,

要使 RSocket 网络路由适用于字符串客户端,请使用

var client = new RSocketClient(new WebSocketTransport("ws://127.0.0.1:7000/"));

Console.WriteLine("Connect Async");
await client.ConnectAsync(new RSocketOptions()
{
    MetadataMimeType = "message/x.rsocket.routing.v0",DataMimeType = "application/json"
});

String json = "{\"Hello\":\"World\"}

byte[] intBytes = BitConverter.GetBytes(6);
string stringBytes = Encoding.Default.GetString(intBytes,1);
string metaData = stringBytes + route;

var stringclient = new RSocketClient.ForStrings(client);
await stringclient.RequestStream(json,metaData)
.ForEachAsync((result) =>
{
    Console.WriteLine($"Result ===> {result}");
});

要让 RSocket 网络路由适用于二进制客户端,请使用

var client = new RSocketClient(new WebSocketTransport("ws://localhost:8080/"));
await client.ConnectAsync(new RSocketOptions()
{
    MetadataMimeType = "message/x.rsocket.routing.v0",DataMimeType = "application/octet-stream"
});

Console.WriteLine("Requesting Raw Protobuf Stream...");

var route = new ReadOnlySequence<byte>(new byte[]
{
    (byte) Encoding.UTF8.GetByteCount("request.stream")
}.Concat(Encoding.UTF8.GetBytes("request.stream")).ToArray());

//Make a Raw binary call
var stream = client.RequestStream(
    resultmapper: result => 
(Data: Encoding.UTF8.GetString(result.data.ToArray()),Metadata: Encoding.UTF8.GetString(result.metadata.ToArray())),data: new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes("test")),metadata: route);

await stream.ForEachAsync(persons => 
Console.WriteLine($"RawDemo.OnNext===>[{persons.Metadata}]{persons.Data}"));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。