diff --git a/Source/lib/SocketRocket/SRWebSocket.m b/Source/lib/SocketRocket/SRWebSocket.m index f05e32af..1359e25d 100755 --- a/Source/lib/SocketRocket/SRWebSocket.m +++ b/Source/lib/SocketRocket/SRWebSocket.m @@ -48,6 +48,9 @@ #error SocketRocket must be compiled with ARC enabled #endif +#include // for TCP_NODELAY +#import // for IPPROTO_TCP + typedef enum { SROpCodeTextFrame = 0x1, @@ -575,6 +578,39 @@ - (void)_initializeStreams; _outputStream.delegate = self; } +- (void)disableNaglesAlgorithmForStream:(NSStream *)stream { + + CFDataRef socketData = NULL; + + // Get socket data + if ([stream isKindOfClass:[NSOutputStream class]]) { + socketData = CFWriteStreamCopyProperty((__bridge CFWriteStreamRef)((NSOutputStream *)stream), kCFStreamPropertySocketNativeHandle); + } else if ([stream isKindOfClass:[NSInputStream class]]) { + socketData = CFReadStreamCopyProperty((__bridge CFReadStreamRef)((NSInputStream *)stream), kCFStreamPropertySocketNativeHandle); + } + + + // get a handle to the native socket + CFSocketNativeHandle *rawsock = (CFSocketNativeHandle *)CFDataGetBytePtr(socketData); + // Disable Nagle's algorythm + static const int kOne = 1; + int err = setsockopt(*rawsock, IPPROTO_TCP, TCP_NODELAY, &kOne, sizeof(kOne)); + if (socketData) { + CFRelease(socketData); + } + + + // Debug info + BOOL isInput = [stream isKindOfClass:[NSInputStream class]]; + NSString * streamType = isInput ? @"INPUT" : @"OUTPUT"; + if (err < 0) { + NSLog(@"Could Not Disable Nagle for %@ stream", streamType); + } else { + NSLog(@"Nagle Is Disabled for %@ stream", streamType); + } +} + + - (void)openConnection; { if (!_scheduledRunloops.count) { @@ -1412,6 +1448,9 @@ - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode; switch (eventCode) { case NSStreamEventOpenCompleted: { SRFastLog(@"NSStreamEventOpenCompleted %@", aStream); + + [self disableNaglesAlgorithmForStream:aStream]; + if (self.readyState >= SR_CLOSING) { return; }