Apache MINA服务器在60秒后关闭活动的UDP“会话”

27

我的客户端-服务器应用在客户端和服务器两端都使用了Apache MINA。通过UDP发送数据可以正常工作,但是一分钟后,服务器会关闭连接(或者说MINA的方式是"会话"),不再响应。

奇怪的是,连接始终保持活动状态。客户端每1000毫秒发送一次数据,服务器用相同的数据进行回答。我发现了MINA的机制来销毁不活动的会话ExpiringMap,它具有会话生存时间的默认值public static final int DEFAULT_TIME_TO_LIVE = 60;,但我没有找到更改它或者更好的更新会话生存时间的方法。

在我的看法中,生存时间应该随着每个传入的数据包自动更新,但是我找不到为什么我的服务器不这样做的原因。我应该明确表示我不想销毁会话吗?还是怎么做?

我的代码与MINA的教程非常相似:

服务器端:

IoAcceptor acceptor = new NioDatagramAcceptor();
try {
    acceptor.setHandler( new UDPHandler() );
    acceptor.bind( new InetSocketAddress(RelayConfig.getInstance().getUdpPort()) );

    acceptor.getSessionConfig().setReadBufferSize( 2048 );
    acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, IDLE_PERIOD );
    System.out.println("RELAY ["+RelayConfig.getInstance().getId()+"]: initialized!");
} catch (IOException e) {
    System.out.println("RELAY ["+RelayConfig.getInstance().getId()+"]: failed: "+e.getLocalizedMessage());
    //e.printStackTrace();
}

客户

NioDatagramConnector connector = new NioDatagramConnector();
connector.getSessionConfig().setUseReadOperation(true);

handler = new UDPHandler();
connector.setHandler(handler);
connector.getSessionConfig().setReadBufferSize(2048);

// try to connect to server!
try {
    System.out.println("Connecting to " + relayIP + ":" + port);
    ConnectFuture future = connector.connect(new InetSocketAddress(relayIP, port));
    future.addListener(new IoFutureListener<IoFuture>() {

        public void operationComplete(IoFuture future) {
            ConnectFuture connFuture = (ConnectFuture)future;
            if( connFuture.isConnected() ){
                UDPClient.setSession(future.getSession());

                Timer timer = new Timer("MyTimerTask", true);
                timer.scheduleAtFixedRate(new MyTimerTask(), 1000, 1000);  // My message is written here every 1000ms
            } else {
                log.error("Not connected...exiting");
            }
        }
    });
    future.awaitUninterruptibly();
} catch (RuntimeIoException e) {
    System.err.println("Failed to connect.");
    e.printStackTrace();
    System.exit(1);
} catch (IllegalArgumentException e) {
    System.err.println("Failed to connect. Illegal Argument! Terminating program!");
    e.printStackTrace();
    System.exit(1);
}

如需更多信息,请在评论中写下来。

编辑:很遗憾我不再拥有那个服务器的访问权限了,但当时问题并没有得到解决。如果还有其他人遇到同样的问题并解决了,请告诉我们。


1
IDLE_PERIOD的值是多少?也许,当接收到空闲状态时,你关闭了连接?你能把你的IO处理代码放上来吗? - Ricardo Cristian Ramirez
1
你使用的是哪个 Mina 版本? - igreenfield
你的MyTimerTask在做什么?我更或多或少地复制了你的代码,除非MyTimerTask像iosession.write一样执行某些操作(并添加到协议编码器链中),否则会在60秒后关闭会话,否则它将保持打开状态。 - user467257
1
@user467257 每秒钟通过 UDPClient.getSession().write() 发送数据。正如您所见,该会话在计时器初始化之前设置。写操作每秒执行一次,并且消息成功到达服务器,因此该会话是活动的并且在每个分钟的每一秒都被使用。 - Jakub Turcovsky
1
TIME_TO_LIVE是IP数据包的一部分,与连接无关。事实上,UDP是无连接的。UDP连接的整个概念是在Mina中实现的。Mina中的某些内容正在关闭IoSession。 - Johnny V
显示剩余4条评论
1个回答

1
我进行了一些研究,找到了下面的链接。你可能需要明确将断开选项设置为false,但也有另一个选项来重置超时选项。 30000的超时时间是30秒,60000是60秒,以此类推... 这些解决方案来自MINA2。不清楚您是否使用该版本或早期版本。从这里,您应该能够添加调用,实现在打开UDP端口时特定选项的设置。

MINA2文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接