如何制作骆驼" Netty4"组件输出端点的结果,但不回显所有输入?

时间:2018-01-08 14:42:35

标签: spring spring-boot apache-camel netty spring-camel

我正在尝试使用Apache Camel来实现TCP游戏服务器。它将接受来自多个人或机器人玩家的双向,同步telnet或SSH连接。

沟通"协议"有点粗糙,并且基于早期版本已经存在的遗留基础设施。基本上,客户端和服务器通过套接字交换I / O(每个客户端一个连接)。

通常,它由一行命令字符串或一行响应字符串组成。但是,在某些情况下,输入或输出可以在考虑之前跨越多个换行符#34;完成"并为另一方的回应做好准备。所以我的计划是:

  1. 使用Spring Boot和Apache Camel创建TCP套接字服务器,后者使用#34; Netty4"成分

  2. 使用聚合从套接字连接收集传入的文本行。根据检测到的输入类型,将它们汇总成一行或多行的消息。

  3. 将生成的消息传递给端点,端点解析输入并将相应的响应返回给套接字。

  4. 我可以显示任何其他代码或Spring配置,但我的问题的核心似乎是我宣布的路线:

    @Component
    public class EchoRoute extends RouteBuilder {
    
        @Override
        public void configure() throws Exception {
    
            // "sync=true" seems necessary to return any response to the client at all
            //
            // "textline=true&autoAppendDelimiter=false" seem necessary to properly handle 
            //     the socket input at newline-terminated strings, rather than processing 
            //     input byte-by-byte
            from("netty4:tcp://localhost:4321?sync=true&textline=true&autoAppendDelimiter=false")
    
                    // This line, and the corresponding `.header("incoming")` line below, are 
                    // perhaps a bit dodgy.  I'm assuming that all messages on the route 
                    // from a given client socket are already effectively "correlated", and 
                    // that messages from multiple client sockets are not inter-mingled 
                    // here.  So I'm basically wildcard-ing the correlation mechanism.  If my 
                    // assumption is wrong, then I'm not sure how to correlate by
                    // client socket.
                    .setHeader("incoming", constant(true))
    
                    // Taken from numerous examples I've seen in Camel books and website 
                    // pages.  Just concatenates the correlated messages until 
                    // completion occurs.
                    .aggregate(new AggregationStrategy() {
                        @Override
                        public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
                            if (oldExchange == null) {
                                return newExchange;
                            }
                            final String oldBody = oldExchange.getIn().getBody(String.class);
                            final String newBody = newExchange.getIn().getBody(String.class);
                            oldExchange.getIn().setBody(oldBody + newBody);
                            return oldExchange;
                        }
                    })
    
                    // See comment on "setHeader(...) above.
                    .header("incoming")
    
                    // In this initial testing, aggregation of a particular message is 
                    // considered complete when the last line received is "EOM".
                    .completionPredicate(exchange -> {
                        final String body = exchange.getIn().getBody(String.class);
                        final boolean done = body.endsWith("EOM");
                        return done;
                    })
    
                    // This endpoint will eventually parse the aggregated message and 
                    // perform logic on it.  Right now, it just returning the input message 
                    // with a prefix.
                    .to("bean:echoService");                 
    
        }
    }
    

    当我启动服务器并从单独的终端窗口telnet到端口4321时,我可以在调试器中验证:

    1. 正在按预期在每行输入上调用.completetionPredicate(...)逻辑,

    2. echoService输入行之后,正在按预期调用EOM个端点。传递给端点的消息包含预期的聚合内容。

    3. 然而,有两个问题:

      1. 服务器回显每行输入返回客户端连接,而不是让端点确定响应内容。

      2. 服务器未向客户端发送端点返回值。我将其记录到服务器控制台,否则它会被无声地丢弃。

      3. 有关我在这里可能缺少什么的建议吗?所需的行为是路由将端点的返回值发送到客户端套接字,并且只返回端点的返回值。谢谢!

0 个答案:

没有答案