1

Similar to rsocket routing metadata using RSocket-Java for Spring Rsocket Server but for an RSocket Net Client, we use a spring boot @MessageMapping for websocket endpoint routes on port 7000 which return webfluxes depending on the route. For example:

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

When spring boot server is running locally, to get this flux you can use rsc client

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

Or for a stream

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

To do this programmatically in C# Net it says here that request routing is not yet supported in RSocket Net but can use metadata payload. Has anyone got the Net equivalent of this?

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());

Thanks

rupweb
  • 3,052
  • 1
  • 30
  • 57

2 Answers2

2

You can implement routing metadata until the .NET library officially supports routing / compsite metadata. If you don't need to send any metadata other than routing metadata, you don't need to create composite metadata. Sending only routing metadata is pretty simple.

As you can see from the spec, just add the length of the route name to the first byte. https://github.com/rsocket/rsocket/blob/master/Extensions/Routing.md

I have no knowledge of .NET, so I'll show you how to implement it in Java and JavaScript instead. FYI.

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;
};
Toshiaki Maki
  • 101
  • 1
  • 4
  • Thank you Sir. By the way great work on [rsc](https://github.com/making/rsc) its really helpful. Even for Net ;-) – rupweb Feb 04 '21 at 06:54
  • thanks for the feedback! BTW, you don't need to use the jar file as I have recently released a native binary for windows ;) – Toshiaki Maki Feb 05 '21 at 02:41
  • The equivalent to `fromCharCode` in C# for say an `int i = 6` is `Encoding.Default.GetString(BitConverter.GetBytes(i), 0, 1);` – rupweb Feb 12 '21 at 11:17
0

To get the RSocket net routes working for string client, use

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, 0, 1);
string metaData = stringBytes + route;

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

To get the RSocket net routes working for binary client, use

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}"));
rupweb
  • 3,052
  • 1
  • 30
  • 57
  • I am using TCP socket connection, my client stops receiving messages after 10 messages. is there any property I am missing? – juggernaut Aug 02 '21 at 17:36