rsocketrsocket-java

RSocket Net client request stream routing metadata to spring boot @MessageMapping routes


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


Solution

  • 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}"));