如何使用Spring集成DSL TCP中的消息标头路由



我有2个服务器端服务,我希望使用消息标头向他们路由消息,其中远程客户端将服务标识放入字段type

是从服务器端配置的代码段,正确的方法吗?它引发了铸造异常,表明route()仅参见有效载荷,但不要参见消息标头。同样,春季集成手册中的所有示例仅显示基于有效载荷的决策。

@Bean
public IntegrationFlow serverFlow( // common flow for all my services, currently 2
        TcpNetServerConnectionFactory serverConnectionFactory,
        HeartbeatServer heartbeatServer,
        FeedServer feedServer) {
    return IntegrationFlows
            .from(Tcp.inboundGateway(serverConnectionFactory))
            .<Message<?>, String>route((m) -> m.getHeaders().get("type", String.class),
                (routeSpec) -> routeSpec
                .subFlowMapping("hearbeat", subflow -> subflow.handle(heartbeatServer::processRequest))
                .subFlowMapping("feed", subflow -> subflow.handle(feedServer::consumeFeed)))
            .get();
}

客户端配置:

@Bean
public IntegrationFlow heartbeatClientFlow(
        TcpNetClientConnectionFactory clientConnectionFactory,
        HeartbeatClient heartbeatClient) {
    return IntegrationFlows.from(heartbeatClient::send,  e -> e.poller(Pollers.fixedDelay(Duration.ofSeconds(5))))
            .enrichHeaders(c -> c.header("type", "heartbeat"))
            .log()
            .handle(outboundGateway(clientConnectionFactory))
            .handle(heartbeatClient::receive)
            .get();
}
@Bean
public IntegrationFlow feedClientFlow(
        TcpNetClientConnectionFactory clientConnectionFactory) {
    return IntegrationFlows.from(FeedClient.MessageGateway.class)
            .enrichHeaders(c -> c.header("type", "feed"))
            .log()
            .handle(outboundGateway(clientConnectionFactory))
            .get();
}

和往常

没有标准的方法可以通过原始TCP发送标头。您需要以某种方式将它们编码到有效载荷中(并在服务器端提取它们)。

该框架为您提供了一种机制,但需要额外的配置。

请参阅文档。

特别是...

MapJsonSerializer使用Jackson ObjectMapper在地图和JSON之间进行转换。您可以将此序列化器与MessageConvertingTcpMessageMapperMapMessageConverter结合使用以传输选定的标头和JSON中的有效负载。

我会尝试一些时间创建一个如何使用它的示例。

但是,当然,您可以滚动自己的编码/解码。

编辑

这是使用JSON通过TCP传达消息标头的示例配置...

@SpringBootApplication
public class TcpWithHeadersApplication {
    public static void main(String[] args) {
        SpringApplication.run(TcpWithHeadersApplication.class, args);
    }
    // Client side
    public interface TcpExchanger {
        public String exchange(String data, @Header("type") String type);
    }
    @Bean
    public IntegrationFlow client(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(TcpExchanger.class)
                .handle(Tcp.outboundGateway(Tcp.netClient("localhost", port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .get();
    }
    // Server side
    @Bean
    public IntegrationFlow server(@Value("${tcp.port:1234}") int port) {
        return IntegrationFlows.from(Tcp.inboundGateway(Tcp.netServer(port)
                        .deserializer(jsonMapping())
                        .serializer(jsonMapping())
                        .mapper(mapper())))
                .log(Level.INFO, "exampleLogger", "'Received type header:' + headers['type']")
                .route("headers['type']", r -> r
                        .subFlowMapping("upper",
                                subFlow -> subFlow.transform(String.class, p -> p.toUpperCase()))
                        .subFlowMapping("lower",
                                subFlow -> subFlow.transform(String.class, p -> p.toLowerCase())))
                .get();
    }
    // Common
    @Bean
    public MessageConvertingTcpMessageMapper mapper() {
        MapMessageConverter converter = new MapMessageConverter();
        converter.setHeaderNames("type");
        return new MessageConvertingTcpMessageMapper(converter);
    }
    @Bean
    public MapJsonSerializer jsonMapping() {
        return new MapJsonSerializer();
    }
    // Console
    @Bean
    @DependsOn("client")
    public ApplicationRunner runner(TcpExchanger exchanger,
            ConfigurableApplicationContext context) {
        return args -> {
            System.out.println("Enter some text; if it starts with a lower case character,n"
                    + "it will be uppercased by the server; otherwise it will be lowercased;n"
                    + "enter 'quit' to end");
            Scanner scanner = new Scanner(System.in);
            String request = scanner.nextLine();
            while (!"quit".equals(request.toLowerCase())) {
                if (StringUtils.hasText(request)) {
                    String result = exchanger.exchange(request,
                            Character.isLowerCase(request.charAt(0)) ? "upper" : "lower");
                    System.out.println(result);
                }
                request = scanner.nextLine();
            }
            scanner.close();
            context.close();
        };
    }
}

相关内容

  • 没有找到相关文章

最新更新