我使用 Objective-C 的 SocketRocket 库连接到 websocket:
-(void)open {
if( self.webSocket ) {
[self.webSocket close];
self.webSocket.delegate = nil;
}
self.webSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"ws://192.168.0.254:5864"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20]];
self.webSocket.delegate = self;
[self.webSocket open];
}
打开连接完全没问题。建立连接后调用委托(delegate)。
-(void)webSocketDidOpen:(SRWebSocket *)webSocket {
NSLog(@"WebSocket is open");
}
但是当我想关闭连接时,什么也没有发生。
-(void)close {
if( !self.webSocket )
return;
[self.webSocket close];
self.webSocket.delegate = nil;
}
没有调用成功关闭连接的委托(delegate)。谁能告诉我为什么会这样?
感谢您阅读我的问题。
最佳答案
我发现委托(delegate)从未被调用,因为 websocket 从未真正关闭过。 SRWebSocket 中的 websocket 关闭发生在 pumpWriting 方法中,如下所示:
if (_closeWhenFinishedWriting &&
_outputBuffer.length - _outputBufferOffset == 0 &&
(_inputStream.streamStatus != NSStreamStatusNotOpen &&
_inputStream.streamStatus != NSStreamStatusClosed) &&
!_sentClose) {
_sentClose = YES;
[_outputStream close];
[_inputStream close];
if (!_failed) {
dispatch_async(_callbackQueue, ^{
if ([self.delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)]) {
[self.delegate webSocket:self didCloseWithCode:_closeCode reason:_closeReason wasClean:YES];
}
});
}
_selfRetain = nil;
NSLog(@" Is really closed and released ");
}
else {
NSLog(@" Is NOT closed and released ");
}
所有流和保留 websocket 的对象都在那里关闭或删除。只要它们仍然打开,套接字就不会适当关闭。但是在我的程序中从未发生过关闭,因为当我尝试关闭 websocket 时,_closeWhenFinishedWriting 始终为 NO。
此 bool 值仅在 disconnect 方法中设置一次。
- (void)_disconnect;
{
assert(dispatch_get_current_queue() == _workQueue);
SRFastLog(@"Trying to disconnect");
_closeWhenFinishedWriting = YES;
[self _pumpWriting];
}
但是在SRWebSocket中调用closeWithCode方法时,disconnect只会在一种情况下被调用,即如果websocket处于连接状态。
BOOL wasConnecting = self.readyState == SR_CONNECTING;
SRFastLog(@"Closing with code %d reason %@", code, reason);
dispatch_async(_workQueue, ^{
if (wasConnecting) {
[self _disconnect];
return;
}
这意味着,如果套接字处于另一种状态,则 websocket 永远不会真正关闭。一种解决方法是始终调用 disconnect 方法。至少它对我有用,一切似乎都很好。
如果有人知道为什么 SRWebSocket 是这样实现的,请对该答案发表评论并帮助我。
关于objective-c - WebSocket 连接未使用 SocketRocket 关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15530437/