【问题标题】:rsocket-js routing fireAndForget to Spring Boot @MessageMappingrsocket-js 路由 fireAndForget 到 Spring Boot @MessageMapping
【发布时间】:2021-05-13 08:23:46
【问题描述】:

据我了解,RSocket-JS 支持使用 encodeCompositeMetadataencodeRoute 路由消息,但是,我无法让服务器接受 fireAndForget 消息。服务器不断记录以下消息:

o.s.m.r.a.support.RSocketMessageHandler : No handler for fireAndForget to ''

这是我试图触发的服务器映射:

    @Controller
    public class MockController {
        private static final Logger LOGGER = LoggerFactory.getLogger(MockController.class);
    
        @MessageMapping("fire-and-forget")
        public Mono<Void> fireAndForget(MockData mockData) {
            LOGGER.info("fireAndForget: {}", mockData);
            return Mono.empty();
        }
    }

这是尝试建立连接的 TypeScript 代码:

    client.connect().subscribe({
        onComplete: socket => {
            console.log("Connected to socket!")
            socket.fireAndForget({
                data: { someData: "Hello world!" },
                metadata: encodeCompositeMetadata([[MESSAGE_RSOCKET_ROUTING, encodeRoute("fire-and-forget")]])
            });
        },
        onError: error => console.error(error),
        onSubscribe: cancel => {/* call cancel() to abort */ }
    });

我也尝试过在互联网上找到的其他方式 (metadata: String.fromCharCode('route'.length)+'route') 添加路由,但似乎都不起作用。

我需要做些什么来格式化路由以使 Spring Boot 服务器能够识别并正确路由消息?

【问题讨论】:

    标签: spring-boot rsocket rsocket-js


    【解决方案1】:

    二进制仅在使用 CompositeMetadata 时进行通信

    请确保您已使用二进制编解码器将ClientTransport 配置为follows

    new RSocketWebSocketClient(
        {
          url: 'ws://<host>:<port>'
        },
        BufferEncoders,
      ),
    

    拥有二进制编码器,您将能够使用复合元数据正确发送您的路线。

    另外,请确保您已将metadataMimeType 配置为:

    ...
    const metadataMimeType = MESSAGE_RSOCKET_COMPOSITE_METADATA.string; // message/x.rsocket.composite-metadata.v0
    
    new RSocketClient<Buffer, Buffer>({
      setup: {
        ...
        metadataMimeType,
      },
      transport: new RSocketWebSocketClient(
        {
          url: 'ws://<host>:<port>',
        },
        BufferEncoders,
      ),
    });
    

    注意,一旦启用 BufferEncoders,您的 JSONSerializer 将无法工作,您需要将自己的 JSON 编码为二进制(我建议这样做,因为在未来的版本中,我们将取消对完全序列化器概念)。因此,您的请求必须按照以下示例进行调整:

    client.connect().subscribe({
            onComplete: socket => {
                console.log("Connected to socket!")
                socket.fireAndForget({
                    data: Buffer.from(JSON.stringify({ someData: "Hello world!" })),
                    metadata: encodeCompositeMetadata([[MESSAGE_RSOCKET_ROUTING, encodeRoute("fire-and-forget")]])
                });
            },
            onError: error => console.error(error),
            onSubscribe: cancel => {/* call cancel() to abort */ }
        });
    

    在 Spring 后端为您的有效负载使用 @Payload 注释

    另外,要处理来自客户端的任何数据并让 Spring 知道指定的参数参数是您传入的请求数据,您必须使用 @Payload 注释对其进行注释:

    @Controller
        public class MockController {
            private static final Logger LOGGER = LoggerFactory.getLogger(MockController.class);
        
            @MessageMapping("fire-and-forget")
            public Mono<Void> fireAndForget(@Payload MockData mockData) {
                LOGGER.info("fireAndForget: {}", mockData);
                return Mono.empty();
            }
        }
    

    【讨论】:

    • 我将代码更改为您提供的示例,起初它似乎有效。服务器停止输出有关无法识别路线的错误。现在它只是不输出任何东西......服务器映射的配置如 Java 代码中所示。你知道为什么它不会触发fireAndForget()吗?是因为服务器无法识别复合元数据吗?我猜我可能只使用 MESSAGE_RSOCKET_ROUTING mimetype,但是编码路由的代码是什么?
    • fireAndForget 对客户端没有任何响应。如果您希望获得任何价值,请尝试requestResponse(我是否遗漏了您的问题?)
    • 另外,试试这个 rsocket-js 和 spring 的工作示例 -> github.com/OlegDokuka/rsocket-crosslanguage-example
    • 另外,刚刚注意到,您的输入参数没有注释。请在您的 MockData 附近添加 @Payload 注释,这可能是您的问题的原因
    • 我不等待服务器的响应。我试图让服务器将接收到的数据记录到控制台,但它没有。我使用 RSocket CLI 进行了尝试,并且成功了,这意味着客户端存在问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-10-25
    相关资源
    最近更新 更多