swift WebSocket Socket.IO Starscream 重连问题

问题

在正常握手完成后,服务器重启,客户端ping超时之后,触发重连事件。
控制台也打印了重连的信息,第一次重连没有成功,服务器拒绝重连,客户端“没有”收到信息,控制台打印了发送重连的请求,但是服务器端收不到。导致客户端一直去重连,服务器端一直没收到任何信息。相互陷入困境,各种查资料,看文档,各自都没有发现问题。
官方的文档也是相当少,都是大同小异

思路

看了不少文档,sdk文档,最后锁定在基层发送给服务器的到底是什么,重连究竟是如何实现的
最终发现,在SocketManager.swiftSocketIOStatus文件中

open func connect() {
        guard !status.active else {
            DefaultSocketLogger.Logger.log("Tried connecting an already active socket", type: SocketManager.logType)

            return
        }

        if engine == nil || forceNew {
            addEngine()
        }

        status = .connecting

        engine?.connect()
    }

 // MARK: Properties
    /// - returns: True if this client/manager is connected/connecting to a server.
  public var active: Bool {
        return self == .connected || self == .connecting
    }

    public var description: String {
        switch self {
        case .connected:    return "connected"
        case .connecting:   return "connecting"
        case .disconnected: return "disconnected"
        case .notConnected: return "notConnected"
        }
    }

在发送重连之时,会先把 status 状态 改为 connecting
status = .connecting 这就导致 guard !status.active else { return} 永远 return ,下面真正去发送连接的事件没有触发,本地只是在循化打印去重连的日志而已,进入假重连模式。

解决方法:

public var active: Bool {
        return self == .connected //|| self == .connecting
    }

关于收不到服务器发送的错误信息问题

经过跟踪发现,服务器返回的消息可能因为格式等问题的存在,拿到的信息在

NWConnection.State
 case waiting(NWError) 

在 waiting中,而Starscream框架中

 guard let conn = connection else {
            return
        }
        conn.stateUpdateHandler = { [weak self] (newState) in
            switch newState {
            case .ready:
                self?.delegate?.connectionChanged(state: .connected)
            case .waiting://此处需要修改 
                break
            case .cancelled:
                self?.delegate?.connectionChanged(state: .cancelled)
            case .failed(let error):
                self?.delegate?.connectionChanged(state: .failed(error))
            case .setup, .preparing:
                break
            @unknown default:
                break
            }
        }

可以看到 框架对于waiting的错误信息是不做处理的,所以看不到任何服务器的错误信息打印,由此可见,还是不能过度信任第三方框架的,此问题解决了三天,开始都没有想到是框架的问题希望后来者不用走过多的弯路。

解决方案

   case .waiting(let error):
                self?.delegate?.connectionChanged(state: .waiting(error))

WSEngine 、Transport文件中分别修改如下

public enum ConnectionState {
    case connected
    case waiting(Error?)
    case cancelled
    case failed(Error?)
....
}

public func connectionChanged(state: ConnectionState) {
        switch state {
....
   case .waiting(let error):
            broadcast(event: .error(error))
            break
....
}

这样外面就能收到服务器的拒绝信息了

你可能感兴趣的:(swift WebSocket Socket.IO Starscream 重连问题)