@@ -295,6 +295,14 @@ + (BOOL)automaticallyNotifiesObserversOfReadyState {
295
295
return NO ;
296
296
}
297
297
298
+ -(void )_onTimeout
299
+ {
300
+ if (self.readyState == SR_CONNECTING) {
301
+ NSError *error = SRErrorWithDomainCodeDescription (NSURLErrorDomain , NSURLErrorTimedOut, @" Timed out connecting to server." );
302
+ [self _failWithError: error];
303
+ }
304
+ }
305
+
298
306
// /--------------------------------------
299
307
#pragma mark - Open / Close
300
308
// /--------------------------------------
@@ -307,18 +315,12 @@ - (void)open
307
315
_selfRetain = self;
308
316
309
317
if (_urlRequest.timeoutInterval > 0 ) {
310
- dispatch_time_t popTime = dispatch_time (DISPATCH_TIME_NOW, (int64_t )(_urlRequest.timeoutInterval * NSEC_PER_SEC));
311
- dispatch_after (popTime, dispatch_get_main_queue (), ^{
312
- if (self.readyState == SR_CONNECTING) {
313
- NSError *error = SRErrorWithDomainCodeDescription (NSURLErrorDomain , NSURLErrorTimedOut, @" Timed out connecting to server." );
314
- [self _failWithError: error];
315
- }
316
- });
318
+ [self performSelector: @selector (_onTimeout ) withObject: nil afterDelay: _urlRequest.timeoutInterval];
317
319
}
318
320
319
321
_proxyConnect = [[SRProxyConnect alloc ] initWithURL: _url];
320
322
321
- __weak __typeof__ (self) wself = self;
323
+ __weak __typeof (self) wself = self;
322
324
[_proxyConnect openNetworkStreamWithCompletion: ^(NSError *error, NSInputStream *readStream, NSOutputStream *writeStream) {
323
325
[wself _connectionDoneWithError: error readStream: readStream writeStream: writeStream];
324
326
}];
@@ -419,14 +421,23 @@ - (void)_readHTTPHeader;
419
421
_receivedHTTPHeaders = CFHTTPMessageCreateEmpty (NULL , NO );
420
422
}
421
423
424
+ // Uses weak self object in the block, otherwise Consumers will retain SRWebSocket instance,
425
+ // and SRWebSocket instance also hold consumers, cycle reference will occur.
426
+ __weak __typeof (self) wself = self;
427
+
422
428
[self _readUntilHeaderCompleteWithCallback: ^(SRWebSocket *socket, NSData *data) {
423
- CFHTTPMessageAppendBytes (_receivedHTTPHeaders, (const UInt8 *)data.bytes , data.length );
424
429
425
- if (CFHTTPMessageIsHeaderComplete (_receivedHTTPHeaders)) {
426
- SRDebugLog (@" Finished reading headers %@ " , CFBridgingRelease (CFHTTPMessageCopyAllHeaderFields (_receivedHTTPHeaders)));
427
- [self _HTTPHeadersDidFinish ];
430
+ __strong __typeof (wself) sself = wself;
431
+ if (sself == nil )
432
+ return ;
433
+
434
+ CFHTTPMessageAppendBytes (sself.receivedHTTPHeaders , (const UInt8 *)data.bytes , data.length );
435
+
436
+ if (CFHTTPMessageIsHeaderComplete (sself.receivedHTTPHeaders )) {
437
+ SRDebugLog (@" Finished reading headers %@ " , CFBridgingRelease (CFHTTPMessageCopyAllHeaderFields (sself.receivedHTTPHeaders )));
438
+ [sself _HTTPHeadersDidFinish ];
428
439
} else {
429
- [self _readHTTPHeader ];
440
+ [sself _readHTTPHeader ];
430
441
}
431
442
}];
432
443
}
@@ -1127,6 +1138,16 @@ - (void)_scheduleCleanup
1127
1138
1128
1139
_cleanupScheduled = YES ;
1129
1140
1141
+ // _consumers retain SRWebSocket instance by block copy, if there are consumers here, clear them.
1142
+ [_consumers removeAllObjects ];
1143
+ [_consumerPool clear ];
1144
+
1145
+ // Cancel the timer which retains SRWebSocket instance.
1146
+ // If we don't cancel the timer, the 'dealloc' method will be invoked only after the time (default: 60s) have come, which may cause memory increase.
1147
+ dispatch_async (dispatch_get_main_queue (), ^(){
1148
+ [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector (_onTimeout ) object: nil ];
1149
+ });
1150
+
1130
1151
// Cleanup NSStream delegate's in the same RunLoop used by the streams themselves:
1131
1152
// This way we'll prevent race conditions between handleEvent and SRWebsocket's dealloc
1132
1153
NSTimer *timer = [NSTimer timerWithTimeInterval: (0 .0f ) target: self selector: @selector (_cleanupSelfReference: ) userInfo: nil repeats: NO ];
@@ -1392,7 +1413,7 @@ - (void)_sendFrameWithOpcode:(SROpCode)opCode data:(NSData *)data
1392
1413
1393
1414
- (void )stream : (NSStream *)aStream handleEvent : (NSStreamEvent )eventCode
1394
1415
{
1395
- __weak __typeof__ (self) wself = self;
1416
+ __weak __typeof (self) wself = self;
1396
1417
1397
1418
if (_requestRequiresSSL && !_streamSecurityValidated &&
1398
1419
(eventCode == NSStreamEventHasBytesAvailable || eventCode == NSStreamEventHasSpaceAvailable)) {
0 commit comments