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)
不会调用成功关闭连接的委托.谁能告诉我为什么会这样?
感谢您阅读我的问题.
我发现委托永远不会被调用,因为 websocket 永远不会真正关闭。SRWebSocket 中 websocket 的关闭发生在PumpWriting方法中,如下所示:
\n\nif (_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\nBOOL 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 归档时间: |
|
查看次数: |
6358 次 |
最近记录: |