問題
在正常握手完成后,服務(wù)器重啟吼和,客戶端ping超時之后涨薪,觸發(fā)重連事件。
控制臺也打印了重連的信息炫乓,第一次重連沒有成功刚夺,服務(wù)器拒絕重連,客戶端“沒有”收到信息末捣,控制臺打印了發(fā)送重連的請求光督,但是服務(wù)器端收不到。導(dǎo)致客戶端一直去重連塔粒,服務(wù)器端一直沒收到任何信息。相互陷入困境筐摘,各種查資料卒茬,看文檔,各自都沒有發(fā)現(xiàn)問題咖熟。
官方的文檔也是相當(dāng)少圃酵,都是大同小異
思路
看了不少文檔,sdk文檔馍管,最后鎖定在基層發(fā)送給服務(wù)器的到底是什么郭赐,重連究竟是如何實現(xiàn)的
最終發(fā)現(xiàn),在SocketManager.swift
與 SocketIOStatus
文件中
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"
}
}
在發(fā)送重連之時确沸,會先把 status 狀態(tài) 改為 connecting
status = .connecting
這就導(dǎo)致 guard !status.active else { return}
永遠 return 捌锭,下面真正去發(fā)送連接的事件沒有觸發(fā),本地只是在循化打印去重連的日志而已罗捎,進入假重連模式观谦。
解決方法:
public var active: Bool {
return self == .connected //|| self == .connecting
}
關(guān)于收不到服務(wù)器發(fā)送的錯誤信息問題
經(jīng)過跟蹤發(fā)現(xiàn),服務(wù)器返回的消息可能因為格式等問題的存在桨菜,拿到的信息在
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的錯誤信息是不做處理的,所以看不到任何服務(wù)器的錯誤信息打印倒得,由此可見泻红,還是不能過度信任第三方框架的??,此問題解決了三天霞掺,開始都沒有想到是框架的問題希望后來者不用走過多的彎路谊路。
解決方案
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
....
}
這樣外面就能收到服務(wù)器的拒絕信息了