SwiftSocket icon indicating copy to clipboard operation
SwiftSocket copied to clipboard

Listening to incoming messages in another thread

Open Lulli4444 opened this issue 6 years ago • 2 comments

Hi, I need my client to listen to incoming messages from the server. This is the code I've written: ... // Connection successful 🎉 case .success: print("--> Connected: waiting for a message..") sleep(1); self.connected = true self.sockTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.readSocket), userInfo: nil, repeats: true) break ...

func readSocket(){ if client != nil { if let data = client.read(1024,timeout: 5) { ...

The problem is that my whole app "freeze" every 5 seconds. I suppose that it is listening for messages, but obviously I don't want this behaviour. I've read to dispatch the reading to another thread, but I don't know how to do it. Could you please help me? Thanks!

Lulli4444 avatar Aug 16 '17 08:08 Lulli4444

Late response, but still useful.

Define some variables within the class

    var connected = false
    var client: TCPClient? = nil
    
    var readingWorkItem: DispatchWorkItem? = nil
    var readingQueue = DispatchQueue(label: "Socket connections for reading")

Call this after the connection has been made:

connected = true
pollForResponse(for: client!)

Handle the data feed in a loop in a background process:

    var message = ""
    
    /// Handle message coming from the reading part
    func handleMessage(){
        let str = self.message
        
        print(str) // Do whatever you want with the response message
        
        // Reset message
        self.message = ""
    }

    /// Handles readings in the background
    ///
    /// - Parameter client: client with active connection
    func pollForResponse(for client: TCPClient){
        if(connected){
            readingWorkItem = DispatchWorkItem {
                guard let item = self.readingWorkItem else { return }
                
                // read incoming characters one at a time and add to message
                while !item.isCancelled {
                    guard let d = client.read(1, timeout: 1) else { continue }
                    
                    let c = String(bytes: d, encoding: .utf8)
                    self.message += c!
                    
                    if (c == "\n") {        // '\n'
                        self.handleMessage()
                    }
                }
            }
            readingQueue.async(execute: readingWorkItem!)
        }
    }

xoniq avatar Oct 20 '17 09:10 xoniq

If it helps I wrapped my entire sending of a request and reading the response into it's own background async call. This eliminated the application hang. Originally the code that executed was on the main thread.

DispatchQueue.global(qos: .background).async { // add your code here. }

nneuberger1 avatar Mar 19 '18 20:03 nneuberger1