"Tried connecting on an already connected socket" - Socket.IO-Client-Swift - ios

I am using swift 4 and Socket.IO-Client-Swift, '~>13.1.1' (latest version).
I tried to call socket.connect() after adding socket handlers but I was getting an error "Tried connecting socket when engine isn't open". So I have added socket.connect() code inside a timer and calling it after 5 seconds, so engine was already opened by that time and not getting that error anymore.
But now I am getting the error "Tried connecting on an already connected socket", even though connect client event handler was never called.
I have gone through the documentation and all the issues that were posted on git but no explanation on how to solve this or why this error even occurs.
You can find the code and console log below.
let manager = SocketManager(socketURL: URL(string: "https://socket.******.**")!, config: [.log(true),.connectParams(["token":Utils.getToken()]),.reconnects(true)])
socket = manager.socket(forNamespace: "/**********")
console log:
2018-02-01 02:20:00.810496+0530 *******[2476:1630437] LOG SocketIOClient{/**********}: Adding handler for event: connect
2018-02-01 02:20:00.837403+0530 *******[2476:1630437] LOG SocketIOClient{/**********}: Adding handler for event: message
2018-02-01 02:20:00.838168+0530 *******[2476:1630437] LOG SocketManager: Manager is being released
2018-02-01 02:20:05.815458+0530 *******[2476:1630437] LOG SocketIOClient{/**********}: Tried connecting on an already connected socket
From the console log, you can see that I am getting "Manager is being released" error msg. Is there a way to retain the manager object? Is that the main reason behind this issue?

Sockets created through the manager are retained by the manager. So at the very least, a single strong reference to the manager must be maintained to keep sockets alive. (As per docs, https://nuclearace.github.io/Socket.IO-Client-Swift/Classes/SocketManager.html)
Easiest way to fix this is create singleton class to retain the manager object
open class SocketConnection {
open static let `default` = SocketConnection()
private let manager: SocketManager
private var socket: SocketIOClient
private init() {
manager = SocketManager(socketURL: URL(string: "https://socket.******.**")!, config: [.log(true),.connectParams(["token":Utils.getToken()]),.reconnects(true)])
socket = manager.socket(forNamespace: "/**********")
}
}

Related

Resubscribing to MQTT Topic when Network ist Lost

I have developed a Quarkus app with which I want to receive and process MQTT messages.
This also works so far.
My problem is that when the internet goes down at the MQTT broker and the app reconnects afterwards, the app reconnects to the broker but no messages are received. I think that the "subscribe" method is not called anymore.
How can I solve this problem?
Here is my Config:
mp.messaging.incoming.smarthome/electricity.connector=smallrye-mqtt
mp.messaging.incoming.smarthome/electricity.host=192.168.1.88
mp.messaging.incoming.smarthome/electricity.port=1883
mp.messaging.incoming.smarthome/electricity.reconnect-attempts=3000
mp.messaging.incoming.smarthome/electricity.reconnect-interval-seconds=10
mp.messaging.incoming.smarthome/electricity.qos=1
mp.messaging.incoming.smarthome/electricity.failure-strategy=ignore
Here is my Controller:
#Incoming("smarthome/electricity")
public void consume(byte[] raw) {
String price = new String(raw,StandardCharsets.UTF_8);
String[] parts = price.split(",");
String watt = parts[0].trim();
String timeStamp = parts[1].trim();
byte wattH = Byte.parseByte(watt.replace("WH", ""));
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Europe/Vienna"))
.withHour(Integer.parseInt(timeStamp.split(":")[0]))
.withMinute(Integer.parseInt(timeStamp.split(":")[1]));
Message message = new Message(wattH,now);
System.out.println(message);
service.addToPackage(message);
scheudler.check();
}
Stack Output if i cut the Connection:
2022-09-20 07:50:09,683 ERROR [io.sma.rea.mes.mqtt] (vert.x-eventloop-thread-0) SRMSG17105: Unable to establish a connection with the MQTT broker: java.net.SocketException: Connection reset
If the Connection is back:
2022-09-20 07:50:26,751 INFO [io.ver.mqt.imp.MqttClientImpl] (vert.x-eventloop-thread Connection with 192.168.1.88:1883 established successfully
So the connection seems to be back, but there are no more incoming messages.
I solved the Problem by myself.
I set :
quarkus.arc.remove-unused-beans=none
And now it works fine.
I tried many ways to fix the problem, but this seems to be the issue.
I think there is some bean removed in the runtime when the connection is lost for a too long time.
If anyone can explain why this happens please tell me

Socket-io iOS client says it's connected to server, despite "connection" event not firing on the server

I am having trouble wrapping my mind around this problem with my very basic Socket-IO setup. In short, the iOS client (running Socket.IO-Client-Swift), seems convinced that it has successfully connected to the socket on the server: The SocketIOClient has a status of connected. However, on the server the connection event is never fired.
When running the code below the iOS client prints Socket status: connected to the console once every 15 seconds or so, indicating that it has successfully connected to the server, and that the connection is maintained.
However, on the server, it appears that the "connection" event is never fired. NEW CONNECTION is never printed to the console on the server. The only console output is Server is running on port 4400..., indicating that the server is ready to accept connections.
When attempting to connect to the server via a web browser, NEW CONNECTION is printed to the console of the server, as expected. It appears that the problem is with the iOS code.
The complete code for the client and server is below.
Client:
class GMSockets {
private var manager: SocketManager = SocketManager(socketURL: URL(string: "ws://localhost:4400")!, config: [.log(false), .compress])
private var socket: SocketIOClient
init() {
self.socket = self.manager.defaultSocket
self.socket.on(clientEvent: .connect) { (data, ack) in
print("Socket status: \(self.socket.status)")
self.socket.emit("testEvent", "Hello")
}
self.socket.connect()
}
}
Server:
let port = 4400;
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(port);
console.log(`Server is running on port ${port}...`);
io.sockets.on("connection", function(socket) {
console.log("NEW CONNECTION")
socket.on("testEvent", function(data) {
console.log("Test event recieved")
})
})
I am using Socket.IO-Client-Swift version 15.2.0 on the iOS client, and Socket.io version 3.0.4 on the server.
The documentation for Socket.IO-Client-Swift erroneously suggests that it supports Socket-io 3.0, however it only supports versions 2.x.x. Downgrading socket.io to 2.3.0 (the last 2.x.x release) will fix this issue.

Socket.io swift client disconnects automatically

I am using socket.io swift client in my app (version 13.1.0) Things work fine, but sometimes this scenario occurs:
Socket gets disconnected (3 out of 10 times). After it gets disconnected it tries and gets connected successfully, but after this it gets disconnected again and this forms an infinite loop of connected - disconnected state. I am searched but didn't get any possible solution.
My code is very simple. I have created a singleton class and its code is given as follows:
class SocketIOManager: NSObject {
static let sharedInstance = SocketIOManager()
let manager = SocketManager(socketURL: URL(string: "URL")!, config: [.compress, .log(true), .reconnects(false)])
override init() {
super.init()
let socket = manager.defaultSocket
socket.on("connect") {data, ack in
NSLog("*************** SOCKET CONNECTED")
}
}
func establishConnection() {
let socket = manager.defaultSocket
socket.connect()
}
}
Other than this I am elegantly disconnecting socket when app goes in background and then connecting it again when app comes in foreground.
Things I have tried:
Tried the configs parameters: forceNew(true/false), reconnects(true/false), forceWebsockets(true/false)
In order to keep the connection active, I am sending an empty parameter to the server every 10 seconds, so that it knows that the app is in active state.
My observation:
I am using Alamofire in the same project and it send requests in background thread. Might be possible that at some point of time both libs start using the same background thread and socket connection breaks.
Is this possible? Correct me if I am wrong in my understanding.
What should I do to overcome this socket disconnection problem. I am a newbie to iOS so any help would be appreciated.

internal error when publishing a stream

I'm using the IOS SDK.
Trying to Publish a stream and getting
Error Domain=OTSessionErrorDomain Code=2000
Code:
session = OTSession(apiKey: kApiKey,
sessionId: kSessionId,
delegate: self)
var error: OTError?
session.connect(withToken: kToken,
error: &error)
let settings = OTPublisherSettings()
settings.cameraResolution = .high
settings.cameraFrameRate = .rate30FPS
guard let publisher = OTPublisher(delegate: self, settings: settings) else { return }
session.publish(publisher, error: &error)
I'm getting the error on session.publish
Any idea what can be the problem?
I cant find any list of internal error options.
When i run the example SimpleVideo app with the same credentials everything works good.
Thanks
You might be able to get it working by very little chance because publishing won't be successful until a client has successfully connected to a session. The correct steps should be:
Attempt to connect to a session
Did connect to a session
Attempt to publish to the connected session
So, you can't call publish right after calling connect method. Instead, you should do publishing in sessionDidConnect:. That is the callback delegate method to ensure that a client has connected a session successfully.

Connecting to MQTT happens after publish due to async

I'm using CocoaMQTT to connect and publish events. To publish, its important that I am connected to MQTT. But connect is async and so is publish. I want it to be sequential that first it should connect and once connected then publish so for example if the connect happens after 5mins then publish should happen after that.
https://github.com/emqtt/CocoaMQTT
How exactly can I do that?
Here is my code:
class ViewController: UIViewController {
var iot: MQTTDelegate!
#IBAction func click(_ sender: Any) {
self.iot = IoT(
withClientId: "clientId",
host: "host",
port: 1883
)
iot.connect(username: "username", password: "token")
iot.publish(topic: "hello", message: "")
}
}
If I move connect to a separate button then it works as first I click the connect button and then I click the "click" button so its sequential. How do I make the above code sequential?
I used PromiseKit to promisify the code but I dont know what exactly to fulfill to connect.
It looks like you are trying to establish a connection to an MQTT server and publish a message to a topic, but the connection is being established after the message is published due to asynchronous behavior.
To fix this issue, you can use the connect() method of the MQTTClient class to establish the connection before publishing the message. The connect() method takes a completion block that is called when the connection is established or if an error occurs.
Here is an example of how you could modify your code to establish the connection before publishing the message:
client.connect { error in
if error == nil {
// Connection was successful
client.publish("topic", withString: "Hello, World!")
} else {
// There was an error connecting to the MQTT server
}
}
This way, the connection to the MQTT server will be established before the message is published, and the message will be sent as soon as the connection is ready.

Resources