1

I made socket between my client App with one remote server, by use of single instance of SRWebSocket, for timely stream data between remote server and my client App. I will initialise it and open stream when user login and enter home page.

+ (WebSocket*)shared:(NSString *)server
{
    if (instance == nil || ![server isEqualToString:instance.nodeServer]) {
        instance = [[WebSocket alloc] init];
        topicQueue = [NSMutableArray array];
    }
    instance.nodeServer = server;
    return instance;
}

WebSocket is Encapsulation of SRWebSocket and handles delegate selector of SRWebSocket.

self.socket = [[SRWebSocket alloc] initWithURL:request protocols:supportedProtocols];
[_socket setDelegate:self];

Everything works well when I first create stream and call [socket open], which gets events NSStreamEventHasBytesAvailableNSStreamEventHasSpaceAvailableNSStreamEventOpenCompleted. And streams between my client App with the remote server works well.

The implementation of open is as follow:

- (void)open;
{
    assert(_url);
    NSAssert(_readyState == SR_CONNECTING && _inputStream == nil && _outputStream == nil, @"Cannot call -(void)open on SRWebSocket more than once");

    _selfRetain = self;

    NSInteger port = _url.port.integerValue;
    if (port == 0) {
        if (!_secure) {
            port = 80;
        } else {
            port = 443;
        }
    }

    [self _connectToHost:_url.host port:port];
}

However, my client App gets event NSStreamEventEndEncountered because of something that I don't know. And the delegate selector of NSStreamEvents is invoked as follow:

case NSStreamEventEndEncountered: {
     [self _pumpScanner];
     SRFastLog(@"NSStreamEventEndEncountered %@", aStream);
     if (aStream.streamError) {
         [self _failWithError:aStream.streamError];
     } else {
         if (self.readyState != SR_CLOSED) {
             self.readyState = SR_CLOSED;
             _selfRetain = nil;
         }

         if (!_sentClose && !_failed) {
              _sentClose = YES;
             // If we get closed in this state it's probably not clean because we should be sending this when we send messages
             dispatch_async(_callbackQueue, ^{
                 if ([self.delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)]) {
                     [self.delegate webSocket:self didCloseWithCode:0 reason:@"Stream end encountered" wasClean:NO];
                 }
             });
         }
     }

    break;
}

The state of socket is closed but stream is not nil. And when user enter home page within my client App from login page, [socket open] is called again. However this assert is false, NSAssert(_readyState == SR_CONNECTING && _inputStream == nil && _outputStream == nil, @"Cannot call -(void)open on SRWebSocket more than once"); .

I have thought that assigning socket to nil when received event NSStreamEventEndEncountered but that will initialise one new socket and stream, which is bad performance in my opinion.

Please help me if you know what's wrong or you have better way!

I have search several questions as well as answers in stack overflow but nothing works for me.

Community
  • 1
  • 1
SeraZheng
  • 187
  • 8
  • It looks like you're using the wrong tool for the job if you're just handling static pages- [check out NSURLSession](https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/index.html#//apple_ref/occ/cl/NSURLSession). SRWebSocket appears to be most helpful when you're streaming data, which is why you would only need to open each instance once. – BoombaleOsby Jan 25 '16 at 19:26
  • Also I'd caution you against modifying a third-party library this way - you're either re-implementing (why?) or overriding(!) methods from SRWebSocket; if your -open method is an override you've left out private code and method calls. – BoombaleOsby Jan 25 '16 at 19:34
  • Thank you for your reminder, My intent is to timely stream data between remote server and my client App – SeraZheng Jan 26 '16 at 02:23

0 Answers0