TcpInboundGateway:如何关闭与远程客户端的现有连接

时间:2016-05-03 04:48:31

标签: spring-integration

我正在使用TcpInBoundGateWay接收来自远程客户端的消息。但问题是客户端定期更改其IP。因此,如果其中一个客户端通过IP' X'进行通信,则当客户的IP从' X'更改时,网关将立即与该IP连接。到了' Y'然后与IP建立新的连接,同时与IP' X'活跃。所以现在我有大约10-15个客户端与此网关进行通信,但是如果我netstat -all它提供了与该端口建立的2000-2500连接。

有什么方法可以终止那个旧连接吗?

@SpringBootApplication
@IntegrationComponentScan
public class SpringIntegrationApplication extends SpringBootServletInitializer{

    DataOperations dataOperations =new DataOperations();

    @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();
    }


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SpringIntegrationApplication.class);
    }

    private static Class<SpringIntegrationApplication> applicationClass = SpringIntegrationApplication.class;


    @Bean
    TcpNetServerConnectionFactory cf(){
        TcpNetServerConnectionFactory connectionFactory=new TcpNetServerConnectionFactory(8765);

        connectionFactory.setSingleUse(true);

        return new TcpNetServerConnectionFactory(TCP_PORT);
    }

    @Bean
    TcpInboundGateway tcpGate(){

        TcpInboundGateway gateway=new TcpInboundGateway();
        gateway.setConnectionFactory(cf());
        gateway.setRequestChannel(requestChannel());
        gateway.setRequestTimeout(20000);
        return gateway;
    }

    @Bean
    public MessageChannel requestChannel(){

        return new DirectChannel();
    }
}

来自netstat的连接列表

tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 106.221.201.180:15076   ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.41.100:41965      ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 106.221.136.178:39192   ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 106.221.135.124:2271    ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.57.252:31644      ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.33.219:32134      ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 106.221.218.22:17275    ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.172.42:30130      ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.21.127:16998      ESTABLISHED
tcp6       0      0 ip-XXX-XX-X-XXX.u:10189 27.58.60.160:51374      ESTABLISHED

1 个答案:

答案 0 :(得分:2)

这些客户表现不佳。

如果在这段毫秒内没有收到任何数据,您可以connectionFactory.setSoTimeout(...)并关闭连接。

或者,connectionFactory.setSoKeepAlive(true)将导致操作系统(或更恰当的TCP堆栈)发送ping以检测这些死连接并关闭它们。 keepalive之间的实际时间是在操作系统级别配置的,但必须在套接字上启用它们,这就是此选项的作用。

请参阅javadocs for Socket

Google SO_TIMEOUT和SO_KEEPALIVE了解更多信息。

修改

要显式关闭连接,连接工厂有一个方法...

/**
 * Close a connection with the specified connection id.
 * @param connectionId the connection id.
 * @return true if the connection was closed.
 */
public boolean closeConnection(String connectionId) { ... }

...您可以从来自客户端的消息(标题ip_connectionId)或通过TcpConnectionOpenEvent打开连接时获取特定的连接ID。您还可以获取当前打开的连接ID列表:

/**
 * Returns a list of (currently) open {@link TcpConnection} connection ids; allows,
 * for example, broadcast operations to all open connections.
 * @return the list of connection ids.
 */
public List<String> getOpenConnectionIds() { ... }