unable to maintain WebSocket stable connection

srikanth
srikanth Member Posts: 15 ✭✭
edited January 10 in PubSub+ Event Broker #1

I am experiencing an issue when trying to connect to WebSocket URL in Postman and Xcode IDE for iOS application. After approximately 30 seconds, the connection is automatically disconnected, and I am unable to maintain a continuous connection, both through Postman and Xcode.

The WebSocket URL I am using is: wss://mr-connection-d5h1qye30cs.messaging.solace.cloud:443

URL : wss://mr-connection-d5h1qye30cs.messaging.solace.cloud:443

code :
func
connectToWebSocket() {

    var request = URLRequest(url: URL(string: webSocketURL)!)

  request.timeoutInterval = 5

let authString = "\(userName):\(password)"

let authData = authString.data(using: .utf8)!

let base64AuthString = authData.base64EncodedString()

        request.setValue("Basic \(base64AuthString)", forHTTPHeaderField: "Authorization")

        request.setValue(vpnName, forHTTPHeaderField: "VPN")

        socket = WebSocket(request: reques)

        socket.delegate = self  socket.connect()

    }

Error: WebSocket disconnected with reason: , code: 1001

Please help me out

Answers

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 668 admin

    Hi @srikanth..! This could be due to the default "web transport inactive timeout" value of 30 seconds set by the client profile. I noticed this when using MQTT over WebSockets in a JavaScript app, and if I navigated away from the Chrome tab where the app was running for a while… Chrome kind of puts the tab to sleep, and my WS connection would drop out.

    If you modify the client profile and put the web inactive timeout to 75 seconds, that might help… it fixed my issue. Chrome seems to let the app do its thing every 60 seconds, so I stopped getting timeouts.

    Also, to help verify this, you could check the broker's event.log and look for the CLIENT_CLIENT_DISCONNECT log corresponding to your WS client, and see if the disconnect reason was listed as "keep-alive" or similar.

    Note: if you're using Solace Cloud for your broker service, and it's not a recent broker version (10.9+), you can't edit the client profile directly via the PubSub+ Manager… you need to do it in the Solace Cloud "mission control" console… inside your broker's service, click on the "Manage" tab, and Client Profiles is in the top-right.

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 668 admin
    edited January 13 #3

    Also, when pasting code, start a code block by hitting backtick 3 times. 👍🏼

  • srikanth
    srikanth Member Posts: 15 ✭✭
    edited January 16 #4

    Hi Aaron,

    I hope you're doing well.

    I am currently working on implementing WebSocket functionality for my iOS application, specifically for subscribing and publishing messages to a queue. While I have been able to successfully connect to a WebSocket server and perform publish/subscribe operations using a third-party WebSocket URL(piehost), I am now looking for guidance on how to achieve the same functionality using your platform.

    Could you please provide the iOS WebSocket code or any documentation that outlines the necessary steps for subscribing and publishing messages? Additionally, I would appreciate it if you could include details on how to specify and interact with a particular queue (including the format and usage of queue names within the WebSocket communication).

    Thank you in advance for your support! Any code samples or resources you can share would be greatly appreciated.


    I have created nodes JS web socket URL wss://mr-connection-d5h1qye30cs.messaging.solace.cloud:443




    Source code :

    func connectToWebSocket() {
    var request = URLRequest(url: URL(string: webSocketURL)!)   request.timeoutInterval = 5 let authString = "\(userName):\(password)" let authData = authString.data(using: .utf8)! let base64AuthString = authData.base64EncodedString()         request.setValue("Basic \(base64AuthString)", forHTTPHeaderField: "Authorization")         request.setValue(vpnName, forHTTPHeaderField: "VPN")         socket = WebSocket(request: reques)         socket.delegate = self  socket.connect()     }

    Please check above code and let me know any changes required?

  • srikanth
    srikanth Member Posts: 15 ✭✭

    Hi @Aaron ,

    There is not just an issue with disconnection time; when I try to send a message to the WebSocket URL, the connection drops immediately after some time. I am unable to maintain a stable WebSocket connection. However, when I tested with another third-party WebSocket URL, I was able to maintain the connection and successfully publish/subscribe to messages.
    I have created nodes JS web socket URL 

    wss://mr-connection-d5h1qye30cs.messaging.solace.cloud:443

    Could you please tried with above url and let us know updates.

  • Aaron
    Aaron Member, Administrator, Moderator, Employee Posts: 668 admin

    WebSockets is just a transport. Just like TCP. You still need to run a protocol on top of it. Trying to interact with the Solace broker with a raw WebSockets interface would be the same as trying to write the correct bytes to a TCP socket that Solace would understand. You need to use a messaging protocol such as SMF (Solace native), MQTT, or AMQP.

    "Just using WebSockets" is not enough. You need a messaing API, connecting over WS.

  • srikanth
    srikanth Member Posts: 15 ✭✭
    edited February 13 #7

    Hello @Aaron,

    I hope you're doing well. In our previous discussions, we've explored how Node.js and Python developers can establish a secure handshake with Solace PubSub+ brokers using certificates and VPN names. Now, I'd like to focus on how we can achieve a similar secure connection in an iOS application using the CocoaMQTT5 library.

    Objective:

    We aim to configure the iOS MQTT client to connect to the Solace broker by specifying the VPN name, similar to the Java implementation.

    Java Implementation Reference:

    private static final String VPN = "general-us10-dev"; // Your VPN name
    private static final String HOST_URL = "tcps://appgendv-us10.messaging.solace.cloud"; // The Solace host URL
    private static final String KEYSTORE_PATH = "/path/to/keystore.jks";
    private static final String KEYSTORE_PASSWORD = "yourKeystorePassword";
    
    public static void main(String[] args) {
        try {
            // Step 1: Create Solace connection factory
            SolConnectionFactoryImpl connectionFactory = new SolConnectionFactoryImpl();
    
            // Set various connection properties
            connectionFactory.setVPN(VPN);
            connectionFactory.setHost(HOST_URL);
            connectionFactory.setAuthenticationScheme("AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE");
            connectionFactory.setSSLKeyStore(KEYSTORE_PATH);
            connectionFactory.setSSLKeyStorePassword(KEYSTORE_PASSWORD);
            connectionFactory.setSSLValidateCertificate(true);
    
            // Step 2: Create connection and session
            Connection connection = connectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    

    iOS Implementation with CocoaMQTT5:

    To replicate this setup in an iOS environment using CocoaMQTT5, we need to configure the MQTT client to specify the VPN name and handle SSL/TLS certificates appropriately.

    import CocoaMQTT
    
    let clientID = "CocoaMQTT5-\(animal!)-" + String(ProcessInfo().processIdentifier)
    let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
    let mqtt5 = CocoaMQTT5(clientID: clientID, host: "appgendv-us10.messaging.solace.cloud", port: 55443, socket: websocket)
    
    let connectProperties = MqttConnectProperties()
    connectProperties.topicAliasMaximum = 0
    connectProperties.sessionExpiryInterval = 0
    connectProperties.receiveMaximum = 100
    connectProperties.maximumPacketSize = 500
    
    mqtt5.connectProperties = connectProperties
    
    mqtt5.enableSSL = true
    mqtt5.username = ""
    mqtt5.password = "" 
    mqtt5.keepAlive = 60
    mqtt5.delegate = self
    mqtt5.logLevel = .debug
    mqtt5.clearSession = true
    
    

    Note:

    Without specifying the VPN name, the connection handshake may not be established successfully( Java and python code base also). It's crucial to ensure that the Solace broker is configured to accept connections from clients specifying the VPN name.

    By following these steps, you should be able to establish a secure connection from your iOS application to the Solace broker, similar to the Java implementation you've provided.

    Please let me know if you need further assistance or clarification on any of the steps.

    Best regards,