SocketClient deinit never called.
Hello! Can you please tell me how to destroy the socket client? This code doesn't help. There are no strong references to the socket in the code. Thanks!
socketManager?.setConfigs([.reconnects(false)])
socketClient?.disconnect()
if socketClient != nil {
socketManager?.removeSocket(socketClient!)
socketClient = nil
}
socketManager = nil
Are you capturing a strong reference to your client in a handler somewhere?
Nope
Could you turn on logs and post the logs for the manager/client when it's trying to disconnect?
Client: 2022-07-12 21:15:04.123333+0300 -[15227:165565] LOG SocketIOClient{/chat}: Closing socket 2022-07-12 21:15:04.123745+0300 -[15227:165565] LOG SocketIOClient{/chat}: Disconnected: Namespace leave 2022-07-12 21:15:04.124176+0300 -[15227:165565] LOG SocketIOClient{/chat}: Handling event: statusChange with data: [disconnected, 1] 2022-07-12 21:15:04.124587+0300 -[15227:165565] LOG SocketIOClient{/chat}: Handling event: disconnect with data: ["Namespace leave"]
Manager: 2022-07-12 21:16:35.673777+0300 -[15227:165565] LOG SocketManager: Manager is being released
This simple example doesn't show the manager or engine holding a strong reference. So would either be something on your end, on something involving ACKs, or more complex example.
let manager: SocketManager
var socket2: SocketIOClient! = manager.socket(forNamespace: "/swift")
func addHandlers(_ socket: SocketIOClient) {
socket.on(clientEvent: .connect) {[weak socket] data, ack in
guard let nsp = data[0] as? String else { fatalError("Should have namespace") }
guard let socket = socket else {
return
}
print("In namespace: \(nsp)")
print(socket.sid)
manager.disconnectSocket(socket)
manager.removeSocket(socket)
socket2 = nil
}
}
socket.connect(withPayload: ["hello": "world"], timeoutAfter: 3) {[weak socket] in
print("failed to connect")
}
2022-07-12 14:23:25.827 Runner[28905:4697677] LOG SocketIOClient{/swift}: Socket connected 2022-07-12 14:23:25.827 Runner[28905:4697677] LOG SocketIOClient{/swift}: Handling event: statusChange with data: [connected, 3] 2022-07-12 14:23:25.827 Runner[28905:4697677] LOG SocketIOClient{/swift}: Handling event: connect with data: ["/swift", ["sid": rd3gJTYUfDNo9Hi1AAAH]] 2022-07-12 14:23:25.827 Runner[28905:4697677] LOG SocketIOClient{/swift}: Disconnected: Namespace leave 2022-07-12 14:23:25.828 Runner[28905:4697715] LOG SocketEngine: Writing poll: 1/swift, has data: false 2022-07-12 14:23:25.828 Runner[28905:4697677] LOG SocketIOClient{/swift}: Handling event: statusChange with data: [disconnected, 1] 2022-07-12 14:23:25.828 Runner[28905:4697715] LOG SocketEnginePolling: Sending poll: 1/swift, as type: 4 2022-07-12 14:23:25.828 Runner[28905:4697677] LOG SocketIOClient{/swift}: Handling event: disconnect with data: ["Namespace leave"] 2022-07-12 14:23:25.828 Runner[28905:4697715] LOG SocketEnginePolling: Created POST string: 41/swift, 2022-07-12 14:23:25.828 Runner[28905:4697677] LOG SocketIOClient{/swift}: Client is being released
CFRunLoopRun()
Ah, so it's something in the Acks.
What does your ack callback look like?
Hmm, I wonder if it has to with this bit of code:
/// Completes an emitWithAck. If this isn't called, the emit never happens.
///
/// - parameter seconds: The number of seconds before this emit times out if an ack hasn't been received.
/// - parameter callback: The callback called when an ack is received, or when a timeout happens.
/// To check for timeout, use `SocketAckStatus`'s `noAck` case.
@objc
public func timingOut(after seconds: Double, callback: @escaping AckCallback) {
guard let socket = self.socket, ackNumber != -1 else { return }
socket.ackHandlers.addAck(ackNumber, callback: callback)
socket.emit(items, ack: ackNumber, binary: binary)
guard seconds != 0 else { return }
socket.manager?.handleQueue.asyncAfter(deadline: DispatchTime.now() + seconds) {[weak socket] in
guard let socket = socket else { return }
socket.ackHandlers.timeoutAck(self.ackNumber)
}
}
Where it doesn't take a weak reference to self... Let me create a fix for that. I can try to put up a beta/patch soonish. Or you could try dev branch with change if possible.
client.emitWithAck("sendMessage", with: [["body": SomeText,
"timestamp": SomeDate,
"attachments": [],
"tags": someTags]])
.timingOut(after: 0) { [weak self] data in
guard let self = self else { return }
switch self.someFunc(data: data) {
case let .success(): doSomething
case .failure: doSomething2
}
}