How to let IBM BlueSocket run on a GUI application and support multi connections?

Recently, I found a pure swift socket server and client called IBM BlueSocket.

It is suitable for me that it does server-cleint communication. It has a pretty simple sample.

but I encountered some problems.

1. How to run it on a GUI application's run loop and support multi connections?

sample code:

#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
    import Darwin
    import Foundation
    import Socket
#elseif os(Linux)
    import Glibc
    import Foundation
    import Socket
#endif


class EchoServer {

    static let QUIT: String = "QUIT"
    let port: Int

    var keepRunning: Bool = true
    var listenSocket: Socket? = nil

    init(port: Int) {
        self.port = port
    }

    deinit {
        self.listenSocket?.close()
    }

    func run() {

        do {

            try self.listenSocket = Socket.create()
            guard let socket = self.listenSocket else {
                print("Unable to unwrap socket...")
                return
            }
            try socket.listen(on: self.port, maxBacklogSize: 10)
            print("Listening on port: \(self.port)")

            // Replace the listening socket with the newly accepted connection...
            try socket.acceptConnection()

            print("Accepted connection from: \(socket.remoteHostname) on port \(socket.remotePort)")
            try socket.write(from: "Hello, type 'QUIT' to end session\n")
            var bytesRead = 0
            repeat {
                let readData = NSMutableData()
                bytesRead = try socket.read(into: readData)
                if bytesRead > 0 {
                    guard let response = String(data: readData as Data, encoding: String.Encoding.utf8) else {
                        print("Error decoding response...")
                        readData.length = 0
                        break
                    }
                    // If the user typed `QUIT`, we'll shutdown the server...
                    if response.hasPrefix(EchoServer.QUIT) {
                        self.keepRunning = false
                    }
                    print("Server received from connection at \(socket.remoteHostname):\(socket.remotePort): \(response) ")
                    // Echo back to the client what we receivied...
                    let reply = "Server response: \n\(response)\n"
                    try socket.write(from: reply)
                }


                // No bytes read, the other side closed the connection...
                if bytesRead == 0 {
                    break
                }


            } while self.keepRunning

            socket.close()
        } catch let error {


            // See if it's a socket error or something else...
            guard let socketError = error as? Socket.Error else {
                print("Unexpected error...")
                return
            }
            print("Error reported: \(socketError.description)")
        }
    }
}

let port = 1337
let server = EchoServer(port: port)
print("Connect using Terminal via 'telnet 127.0.0.1 \(port)'")
server.run()

It’s clear that this server runs synchronously. As such, you’ll have to create a secondary thread to run each connection.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
How to let IBM BlueSocket run on a GUI application and support multi connections?
 
 
Q