我正在尝试使用Apache Camel来实现TCP游戏服务器。它将接受来自多个人或机器人玩家的双向,同步telnet或SSH连接。
沟通"协议"有点粗糙,并且基于早期版本已经存在的遗留基础设施。基本上,客户端和服务器通过套接字交换I / O(每个客户端一个连接)。
通常,它由一行命令字符串或一行响应字符串组成。但是,在某些情况下,输入或输出可以在考虑之前跨越多个换行符#34;完成"并为另一方的回应做好准备。所以我的计划是:
使用Spring Boot和Apache Camel创建TCP套接字服务器,后者使用#34; Netty4"成分
使用聚合从套接字连接收集传入的文本行。根据检测到的输入类型,将它们汇总成一行或多行的消息。
将生成的消息传递给端点,端点解析输入并将相应的响应返回给套接字。
我可以显示任何其他代码或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
时,我可以在调试器中验证:
正在按预期在每行输入上调用.completetionPredicate(...)
逻辑,
在echoService
输入行之后,正在按预期调用EOM
个端点。传递给端点的消息包含预期的聚合内容。
然而,有两个问题:
服务器回显每行输入返回客户端连接,而不是让端点确定响应内容。
服务器未向客户端发送端点返回值。我将其记录到服务器控制台,否则它会被无声地丢弃。
有关我在这里可能缺少什么的建议吗?所需的行为是路由将端点的返回值发送到客户端套接字,并且只返回端点的返回值。谢谢!