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 NSStreamEventHasBytesAvailable
,NSStreamEventHasSpaceAvailable
,NSStreamEventOpenCompleted
. 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.