objective-c - WebSocket 连接未使用 SocketRocket 关闭

标签 objective-c connection 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];
}

打开连接完全没问题。建立连接后调用委托(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/

相关文章:

objective-c - 使 UITableView 的第一个单元格与其他每个单元格不同

java - 连接超时与尝试了所有 : '1' addresses, 但无法通过 HTTP 连接到服务器之间的区别

C# 数据连接最佳实践?

php - Ratchet/网络套接字 : How many clients subscribing to an object?

objective-c - 如何改变 NSScroller 的颜色?

ios - UIPickerView 无法显示 JSON 数组数据

ios - 发送到不可变对象(immutable对象)的变异方法'

Java等待Mysql连接

c# - Firefox 中的 WebSocket

websocket - 这些数字在 socket.io 有效负载中意味着什么?