WebSocket Connection未使用SocketRocket关闭

Phi*_*tto 14 connection objective-c websocket socketrocket

我使用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];
}
Run Code Online (Sandbox Code Playgroud)

打开连接工作完全正常.建立连接后调用委托.

-(void)webSocketDidOpen:(SRWebSocket *)webSocket {

NSLog(@"WebSocket is open");

}
Run Code Online (Sandbox Code Playgroud)

但是,当我想关闭连接时,没有任何反应.

-(void)close {

if( !self.webSocket )
    return;

[self.webSocket close];
self.webSocket.delegate = nil;

}
Run Code Online (Sandbox Code Playgroud)

不会调用成功关闭连接的委托.谁能告诉我为什么会这样?

感谢您阅读我的问题.

Phi*_*tto 4

我发现委托永远不会被调用,因为 websocket 永远不会真正关闭。SRWebSocket 中 websocket 的关闭发生在PumpWriting方法中,如下所示:

\n\n
if (_closeWhenFinishedWriting && \n    _outputBuffer.length - _outputBufferOffset == 0 && \n    (_inputStream.streamStatus != NSStreamStatusNotOpen &&\n     _inputStream.streamStatus != NSStreamStatusClosed) &&\n    !_sentClose) {\n    _sentClose = YES;\n\n    [_outputStream close];\n    [_inputStream close];\n\n    if (!_failed) {\n        dispatch_async(_callbackQueue, ^{\n            if ([self.delegate respondsToSelector:@selector(webSocket:didCloseWithCode:reason:wasClean:)]) {\n                [self.delegate webSocket:self didCloseWithCode:_closeCode reason:_closeReason wasClean:YES];\n            }\n        });\n    }\n\n    _selfRetain = nil;\n\n    NSLog(@" Is really closed and released ");\n}\nelse {\n\n    NSLog(@" Is NOT closed and released ");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

所有流和保留 websocket 的对象都将在那里关闭或删除。只要它们仍然打开,套接字就不会被适当关闭。但我的程序中从未发生过关闭,因为当我尝试关闭 websocket 时,_closeWhenFinishedWriting始终为“否”。

\n\n

该布尔值仅在断开连接方法中设置一次。

\n\n
- (void)_disconnect;\n{\n\nassert(dispatch_get_current_queue() == _workQueue);\nSRFastLog(@"Trying to disconnect");\n_closeWhenFinishedWriting = YES;\n[self _pumpWriting];\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但在 SRWebSocket 中调用closeWithCode方法时,仅在一种情况下才会调用disconnect,即 websocket 处于连接状态。

\n\n
BOOL wasConnecting = self.readyState == SR_CONNECTING;\n\nSRFastLog(@"Closing with code %d reason %@", code, reason);\ndispatch_async(_workQueue, ^{\n\n    if (wasConnecting) {\n        [self _disconnect];\n        return;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着,如果套接字处于另一种状态,则 websocket 将永远不会真正关闭。一种解决方法是始终调用断开连接方法。至少它对我有用,而且一切似乎都很好。

\n\n

如果有人知道为什么 SRWebSocket 是这样实现的,请对此答案发表评论并帮助我。

\n