1

据我了解,RSocket-JS 支持使用encodeCompositeMetadata和路由消息encodeRoute,但是,我无法让服务器接受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 服务器识别路由并正确路由消息的方式格式化路由?

4

1 回答 1

1

使用CompositeMetadata时仅二进制通信

请确保您已按如下ClientTransport方式配置了二进制编解码器:

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,
  ),
});

请注意,一旦启用BufferEncodersJSONSerializer 将无法工作,您需要将 JSON 编码为自己的二进制文件(我建议这样做,因为在未来的版本中,我们将完全删除对 Serializers 概念的支持)。因此,您的请求必须按照以下示例进行调整:

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();
        }
    }
于 2021-05-13T09:07:53.920 回答