client--->server
但是httpcomponent是基于连接池的,那么连接是永远不关闭的话,如何做到判断http请求的socketimout的呢?
代码基于4.4.6
clinet端实际是使用AbstractIOReactor类
for (;;) {
final int readyCount;
try {
readyCount = this.selector.select(this.selectTimeout);
} catch (final InterruptedIOException ex) {
throw ex;
} catch (final IOException ex) {
throw new IOReactorException("Unexpected selector failure", ex);
}
if (this.status == IOReactorStatus.SHUT_DOWN) {
// Hard shut down. Exit select loop immediately
break;
}
if (this.status == IOReactorStatus.SHUTTING_DOWN) {
// Graceful shutdown in process
// Try to close things out nicely
closeSessions();
closeNewChannels();
}
// Process selected I/O events
if (readyCount > 0) {
processEvents(this.selector.selectedKeys());
}
// Validate active channels
validate(this.selector.keys());
// Process closed sessions
processClosedSessions();
// If active process new channels
if (this.status == IOReactorStatus.ACTIVE) {
processNewChannels();
}
// Exit select loop if graceful shutdown has been completed
if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0
&& this.sessions.isEmpty()) {
break;
}
if (this.interestOpsQueueing) {
// process all pending interestOps() operations
processPendingInterestOps();
}
}
validate(this.selector.keys());的时候会判断连接是否已经socketimeout。
protected void timeoutCheck(final SelectionKey key, final long now) {
final IOSessionImpl session = (IOSessionImpl) key.attachment();
if (session != null) {
final int timeout = session.getSocketTimeout();
if (timeout > 0) {
if (session.getLastAccessTime() + timeout < now) {
sessionTimedOut(session);
}
}
}
}
但是这里有个问题,就是这里获取到session.getSocketTimeout(),如果这个连接长时间都没有请求,岂不是这里进行连接的判断
的时候就超时了,不就抛出异常了?
这里其实是在这里:
在cpool归还连接的时候,会将sockettimeout置为0.则不再判断连接的时效性。直到下次新的连接来了,则再设置sockettimeout,再进行超时的判断。
2. 而server端的httpcomponent,则每次真的在判断timeout,通过(代码基于。4和5的DefaultConnectingIOReactor类
都完全不一样了)
InternalChannel
final boolean checkTimeout(final long currentTime) {
final int timeout = getTimeout();
if (timeout > 0) {
final long deadline = getLastReadTime() + timeout;
if (currentTime > deadline) {
try {
onTimeout();
} catch (final CancelledKeyException ex) {
close(CloseMode.GRACEFUL);
} catch (final Exception ex) {
onException(ex);
close(CloseMode.IMMEDIATE);
}
return false;
}
}
return true;
}
这里的getTimeout,也是从InternalDataChannel
@Override
int getTimeout() {
return ioSession.getSocketTimeout();
}
中获取,但是这里真的不会重新设置iosessionimpl的socktTimeout。因此,server端设置的是多少就是多少。
客户端使用的是SingleCoreIOReactor,也不会重新设置socktTimeout。如果设置,也应该是和4.6一样,由前端cpool等
线程池进行操作。因此,这猜测是http请求完毕以后,直接关闭这个链接,
没有让这个SingleCoreIOReactor继续循环的可能性,因为继续循环将造成超时。