I looked into GCDAsyncSocket.m at the code that handles read timeout. If I don't extend the timeout, it seems that socket got closed and there is no option to the socket alive keep. I can't use infinite timeout (timeout = -1) because I still need to know when it is timed out, but also doesn't want it to disconnect. I'm not sure there is a reason behind this. Does anyone know?
- (void)doReadTimeoutWithExtension:(NSTimeInterval)timeoutExtension
{
if (currentRead)
{
if (timeoutExtension > 0.0)
{
currentRead->timeout += timeoutExtension;
// Reschedule the timer
dispatch_time_t tt = dispatch_time(DISPATCH_TIME_NOW, (timeoutExtension * NSEC_PER_SEC));
dispatch_source_set_timer(readTimer, tt, DISPATCH_TIME_FOREVER, 0);
// Unpause reads, and continue
flags &= ~kReadsPaused;
[self doReadData];
}
else
{
LogVerbose(@"ReadTimeout");
[self closeWithError:[self readTimeoutError]];
}
}
}
FYI, there is a pull request at https://github.com/robbiehanson/CocoaAsyncSocket/pull/126 that adds this keep-alive feature but it is not pulled yet.
I am the original author of AsyncSocket, and I can tell you why I did it that way: there are too many ways for protocols to handle timeouts. So I implemented a "hard" timeout and left "soft" timeouts up to the application author.
The usual way to do a "soft" timeout is with an NSTimer
or dispatch_after
. Set one of those up, and when the timer fires, do whatever you need to do. Meanwhile, use an infinite timeout on the actual readData
call. Note that infinite timeouts aren't actually infinite. The OS will still time out after, say, 10 minutes without successfully reading. If you really want to keep the connection alive forever, you might be able to set a socket option.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With