Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.forceWebsockets(true) has issues with reconnect #1500

Open
Rostyk opened this issue Sep 30, 2024 · 3 comments
Open

.forceWebsockets(true) has issues with reconnect #1500

Rostyk opened this issue Sep 30, 2024 · 3 comments

Comments

@Rostyk
Copy link

Rostyk commented Sep 30, 2024

I'm using the socket in a swift iOS app like this:

private var manager: SocketManager!
private var socketIO: SocketIOClient!
.....

 manager = SocketManager(socketURL: URL(string: url)!,
                                config: [
                                    .log(true),
                                    .reconnects(true),
                                    .forceWebsockets(true)
                                    .connectParams(["roomId": nameSpace])])
        
socketIO.on(clientEvent: .reconnect, callback: { [weak self] data, ack in
            NSLog("Socket is in reconnect state")
            self?.state = .reconnecting
})
socketIO = manager.defaultSocket
socketIO.connect()

After the internet connection is lost, no .reconnect event is sent for 25 seconds and there's no way to change that behavior. I see in SocketEngine.swift this piece of code:

public func didReceive(event: Starscream.WebSocketEvent, client: Starscream.WebSocketClient) {
        switch event {
        case let .connected(headers):
            wsConnected = true
            self.client?.engineDidWebsocketUpgrade(headers: headers)
            websocketDidConnect()
        case .cancelled:
            wsConnected = false
            websocketDidDisconnect(error: EngineError.canceled)
        case .disconnected(_, _):
            wsConnected = false
            websocketDidDisconnect(error: nil)
        case let .text(msg):
            parseEngineMessage(msg)
        case let .binary(data):
            parseEngineData(data)
        case _:
            break
        }
 }

So the viabilityChanged(Bool) state is not handled in the didReceive

public enum WebSocketEvent {
    case connected([String: String])
    case disconnected(String, UInt16)
    case text(String)
    case binary(Data)
    case pong(Data?)
    case ping(Data?)
    case error(Error?)
    case viabilityChanged(Bool) // falls into default case and there's no way to subscribe for this event
    case reconnectSuggested(Bool)
    case cancelled
    case peerClosed
}

The viabilityChanged(false) is sent by StarScream in .forceWebsocket(true) mode which indicates that the socket has no physical connection. Instead I don't get the clientEvent: .reconnect until the ping times out, which is 25 seconds usually. The pingTimeout is taken from here:

if let pingInterval = json["pingInterval"] as? Int, let pingTimeout = json["pingTimeout"] as? Int {
       self.pingInterval = pingInterval
       self.pingTimeout = pingTimeout
}

Is there something I'm missing here or it's designed this way and it's okay.
I'm happy to submit pull-request with few tweaks to improve it

@cbiggin
Copy link

cbiggin commented Sep 30, 2024

I think there is already a PR (#1464) but unfortunately the maintainer of this repo has gone MIA.

@Ariandr
Copy link

Ariandr commented Oct 2, 2024

It seems it was resolved and released guys

@cbiggin
Copy link

cbiggin commented Oct 3, 2024

Yes, I was wondering if it had been. @Rostyk v16.1.1 was released 2 days ago so you can probably close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants