Hi there,
This problem happens in our project. I wrote a small mina client application to
show this problem. There are 10 mina clients trying to connect to a server.
When I start mina clients, after while, about 20 minutes or longer, one or two
client connectFuture.isConnected() return true, show being connected to a
server even no server running at all.
Below is my code:
package ca.navcanada.xio.interfaces;
import java.net.InetSocketAddress;
import org.apache.log4j.Logger;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
*
*/
public class MiniTcpClient extends IoHandlerAdapter {
private static final Logger log = Logger.getLogger(MiniTcpClient.class);
private final ConnectFutureListener connectFutureListener;
private volatile ConnectFuture connectFuture;
protected SocketConnector connector;
private InetSocketAddress inetAddress;
public MiniTcpClient(InetSocketAddress inetAddress) {
super();
this.inetAddress = inetAddress;
connector = new NioSocketConnector();
//connector.addListener(ioServiceListener);
connector.getFilterChain().addLast("logging", new
MessageLoggingFilter("MiniTCP"));
connectFutureListener = new ConnectFutureListener();
connector.setHandler(this);
connector.getSessionConfig().setKeepAlive(true);
}
public synchronized void connect() {
// System.out.println("Connecting to " + inetAddress + " ...");
cancelAllSessions();
if (inetAddress == null) {
System.out.println("No address available to connect to");
return;
}
connectFutureListener.setInetAddress(inetAddress);
connectFuture = connector.connect(inetAddress);
connectFuture.addListener(connectFutureListener);
}
public static void main(String[] args) {
MiniTcpClient [] tcpClient = new MiniTcpClient[10];
InetSocketAddress inetAddress1 = new InetSocketAddress("127.0.0.1", 51200);
InetSocketAddress inetAddress2 = new InetSocketAddress("127.0.0.1", 51201);
for (int i = 0; i < 10; i++) {
if (i < 5) {
tcpClient[i] = new MiniTcpClient(inetAddress1);
} else {
tcpClient[i] = new MiniTcpClient(inetAddress2);
}
tcpClient[i].connect();
}
}
/**
* Cancels all established or pending sessions associated with the {@link
#connector}
*/
private void cancelAllSessions() {
// cancel any pending connect attempts
if (connectFuture != null) {
connectFuture.removeListener(connectFutureListener);
connectFuture.cancel();
connectFuture = null;
}
// close any open connections immediately
final boolean immediately = true;
for (IoSession session : connector.getManagedSessions().values()) {
CloseFuture cf = session.close(immediately);
cf.awaitUninterruptibly();
}
}
void retryConnect() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread.sleep interruped on connectionFailoverInterval");
} finally {
connect();
}
}
private class ConnectFutureListener implements IoFutureListener<ConnectFuture> {
private InetSocketAddress inetAddress;
public void setInetAddress(InetSocketAddress inetAddress) {
this.inetAddress = inetAddress;
}
// handle the session close event
final IoFutureListener<CloseFuture> onSessionClose = new
IoFutureListener<CloseFuture>() {
@Override
public void operationComplete(CloseFuture iof) {
System.out.println("Connection to " + iof.getSession().getRemoteAddress() + "
closed.");
}
};
@Override
public void operationComplete(ConnectFuture future) {
// we are connected!
if (future.isConnected()) {
System.out.println("Connection established to " + inetAddress);
// set up closeFuture when the connection is closed.
future.getSession().getCloseFuture().addListener(onSessionClose);
return;
}
// connection failed for whatever reason
//System.out.println("Connection to " + inetAddress + " failed."); //
retryConnect();
retryConnect();
}
}
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
cause.printStackTrace();
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
log.debug("Message sent...");
}
@Override
public void messageReceived(IoSession session, Object message)
throws Exception {
log.debug("Session recv...");
}
@Override
public void sessionClosed(IoSession session) throws Exception {
log.debug("Session closed...");
}
@Override
public void sessionCreated(IoSession session) throws Exception {
log.debug("Session created...");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status)
throws Exception {
log.debug("Session idle...");
}
@Override
public void sessionOpened(IoSession session) throws Exception {
log.debug("Session opened...");
}
}
Thanks in advance,
Susan Wang