Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS 13 URLSessionWebSocketTask当前连接状态_Ios_Swift_Websocket_Urlsession - Fatal编程技术网

iOS 13 URLSessionWebSocketTask当前连接状态

iOS 13 URLSessionWebSocketTask当前连接状态,ios,swift,websocket,urlsession,Ios,Swift,Websocket,Urlsession,我已经设置并实现了我的URLSessionWebSocketDelegate urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) 但是,只有在服务器正确断开连接的情况下,代理才会受到影响。如果连接断开或服务器未提供断开连接代码,则委托功能将永远不会运行。

我已经设置并实现了我的
URLSessionWebSocketDelegate

urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?)
但是,只有在服务器正确断开连接的情况下,代理才会受到影响。如果连接断开或服务器未提供断开连接代码,则委托功能将永远不会运行。我还尝试在断开连接之前和之后检查
URLSessionWebSocketTask
属性
closeCode
closeReason
,除非服务器发送正确的断开连接代码,否则它们不会更改

虽然我可以控制服务器,并且可以确保故意断开连接有一个代码,但如果网络连接断开,会发生什么情况?或者如果服务器宕机?我认为委托函数仍然应该被调用

有趣的是,我的侦听函数得到一个错误,错误状态如下:

Error Domain=NSPOSIXErrorDomain Code=57 "Socket is not connected" UserInfo={NSErrorFailingURLStringKey=[urlomitted], NSErrorFailingURLKey=[urlomitted]
因此,虽然我可以在看到错误57时手动断开套接字,但我不知道这是否适用于所有不同的断开类型


我想我可能是做错了什么,或者这是一个bug,但我找不到其他有同样问题的人,所以我想在提交雷达之前询问一下。

不确定这是一个好方法,但是下面两种解决方案都会在我的代码中捕获服务器/连接丢失事件

a) 您可以在WebSocket接收函数中检测到它,如下所示:

func receiveMessage() {
        webSocketTask?.receive { result in
            defer { self.receiveMessage() }
            switch result {
            case .failure(let error):
                print("Error in receiving message: \(error)")
                let code = (error as NSError).code
                if code == 60 || code == 57 || code == 54 {
                    // deal with error
                }
            case .success(let message):
                switch message {
                case let .string(string):
                    // deal with strings message
                case let .data(data):
                    // deal with data message
                @unknown default:
                    // deal with unknown message
                }
            }
        }
    }  
b) 或者,您可以将urlSession实例方法添加到
URLSessionWebSocketDelegate
,该方法捕获服务器的一般丢失/连接错误

extension BlipSocket: URLSessionWebSocketDelegate {
    func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
        DispatchQueue.main.async {
            self.isConnected = true
        }
    }
    func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
        DispatchQueue.main.async {
            self.isConnected = false
        }
    }
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError: Error?) {
        DispatchQueue.main.async {
            self.connectionError = true
        }
    }
}

您还可以实现
urlSession(\usession:urlSession,task:URLSessionTask,didcompletewitheror error:error?)
这是一个urlsessionelegate。这会在连接失败时触发URLSessionError。我使用了以下实现

 func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    guard let error = error as? URLError else { return }
    
    switch error.errorCode {
    // offline, timedOut
    case -1009, -1001:
        delegate?.didDisconnect(
            reasonCode: UInt16(URLSessionWebSocketTask.CloseCode.abnormalClosure.rawValue),
            error: error)
    default: break
    }
}

这会在第一个失败的请求发出60秒后触发。设置
URLSessionConfiguration
较短的超时似乎不起作用,它总是在60秒后启动,这很糟糕。希望这有帮助,一个更好的解决方案也会很好。你解决这个问题了吗?已经很久了,我不确定我是否找到了解决办法。不过,我知道没有一个直截了当的“修正”。我相信这就是关于这个问题的文件和我正在进行的项目:请随便看看这个方法是否适合你!错误代码57在enum
POSIXErrorCode
中定义为case
ENOTCONN
。当我手动断开websocket任务(如
webSocketTask.cancel)时(使用:.goingAway,原因:nil)
,会调用
urlSession(…DidCloseWithWith.)
urlSession(…didCompleteWithError.)
。可能是因为递归函数正在运行。有没有办法优雅地关闭websocketTask?