Spring集成与gps设备的双向通信
我们正在使用spring集成应用程序从gps设备接收数据。对于当前配置,我们可以从设备接收数据,也可以通过相同的连接将数据发送回设备 当前配置如下所示Spring集成与gps设备的双向通信,gps,spring-integration,two-way,Gps,Spring Integration,Two Way,我们正在使用spring集成应用程序从gps设备接收数据。对于当前配置,我们可以从设备接收数据,也可以通过相同的连接将数据发送回设备 当前配置如下所示 @SpringBootApplication @IntegrationComponentScan public class SpringIntegrationApplication extends SpringBootServletInitializer{ private Integer TIMEOUT=1000*60*10; @V
@SpringBootApplication
@IntegrationComponentScan
public class SpringIntegrationApplication extends SpringBootServletInitializer{
private Integer TIMEOUT=1000*60*10;
@Value("${TCP_PORT}")
private Integer TCP_PORT;
public static void main(String[] args) throws IOException {
ConfigurableApplicationContext ctx = SpringApplication.run(SpringIntegrationApplication.class, args);
System.in.read();
ctx.close();
}
@Bean
TcpNetServerConnectionFactory cf(){
TcpNetServerConnectionFactory connectionFactory=new TcpNetServerConnectionFactory(TCP_PORT);
connectionFactory.setSerializer(new CustomSerializerDeserializer());
connectionFactory.setDeserializer(new CustomSerializerDeserializer());
connectionFactory.setSoTimeout(TIMEOUT);
return connectionFactory;
}
@Bean
TcpInboundGateway tcpGate(){
TcpInboundGateway gateway=new TcpInboundGateway();
gateway.setConnectionFactory(cf());
gateway.setRequestChannel(requestChannel());
gateway.setRequestTimeout(TIMEOUT);
return gateway;
}
@Bean
public MessageChannel requestChannel(){
return new DirectChannel();
}
}
和消息端点
@MessageEndpoint
public class Echo {
@ServiceActivator(inputChannel="requestChannel")
public byte[] echo(byte[] in,@SuppressWarnings("deprecation") @Header("ip_address") String ip){
//here we receive packet data in bytes from gps device
return "".getBytes();//string will contains expected result for device.
}
上述配置适用于单向通信。但我们希望实现双向通信。在服务器和设备之间建立连接后,我们想要明确地发送消息。要通过服务器发送命令,我们不知道设备的ip和端口,所以我们如何通过服务器向连接的设备发送命令
我正在尝试以下解决方案
已创建oubound通道适配器
@Bean
public TcpSendingMessageHandler tcpSendingMessageHandler() {
System.out.println("Creating outbound adapter");
TcpSendingMessageHandler outbound = new TcpSendingMessageHandler();
return outbound;
}
然后为显式消息发送创建网关,这将从我们希望显式发送数据的服务调用
@MessagingGateway(defaultRequestChannel="toTcp")
public static interface tcpSendService {
public byte [] send(String string);
}
在调用gate way following service activator(我们正在设置连接ip和端口)后,这些ip和端口将来自从设备接收数据时建立的连接
@ServiceActivator(inputChannel="toTcp", outputChannel="fromTcp")
public String send(String in){
System.out.println(new String(in));
TcpNetClientConnectionFactory factory = new TcpNetClientConnectionFactory(ip_extracted_from_inbound_connection, port_extarcted_from_inbound_connection);
factory.start();
tcpSendingMessageHandler.setConnectionFactory(factory);
return in;
}
//对于ip和端口提取,我使用以下服务,即入站服务
@ServiceActivator(inputChannel="requestChannel")
public byte[] echo(byte[] in,@Header("ip_address") String ip){
System.out.println(new String(in)+ " ; IP : "+ip);
for (String connectionId : factory.getOpenConnectionIds()) {
if(!lastConection.contains(ip))
lastConection = connectionId;
}
return "hello".getBytes();
}
对于服务激活器,每次调用服务时,我都会设置新的TcpNetClientConnectionFactory。Ip和端口从TcpNetServerConnectionFactory提取。每当设备与服务器连接时,我都会保存其连接ip和端口,使用这些ip和端口通过服务器进行数据传输,但我遇到连接超时问题
请帮助我,并建议我一个解决方案
谢谢。将网关更换为一对 要向连接发送任意消息,必须设置
ip\u connectionId
头
然而,挑战在于如何将回复定向到网关。您需要从请求中捕获replyChannel
标头,并且在收到该ip\u连接ID的答复时,设置replyChannel
标头
不过,这只适用于每次只有一个未完成的请求/回复到每个设备的情况,除非回复中有一些数据可用于将其与请求关联起来
另一个挑战是竞争条件,即设备和服务器同时启动请求。您需要查看入站邮件中的数据,以确定它是请求还是答复。谢谢。正如您所看到的,我使用的是TcpNetServerConnectionFactory,因此我们如何对ie入站和出站适配器使用相同的连接工厂。是否存在相同的示例应用程序。您只需将相同的工厂注入这两个应用程序中;有一个样品。它是基于XML的配置,但同样的技术也适用。它使用聚合器来处理保留replyChannel
的问题,但您可能只需要一个简单的映射。