Ios 用于Swift 1.2同步请求的GCDAsyncSocket

Ios 用于Swift 1.2同步请求的GCDAsyncSocket,ios,swift,asynchronous,sync,gcdasyncsocket,Ios,Swift,Asynchronous,Sync,Gcdasyncsocket,背景: public class SendNet: NSObject, GCDAsyncSocketDelegate { var socket:GCDAsyncSocket! = nil func setupConnection(){ var error : NSError? if (socket == nil) { socket = GCDAsyncSocket(delegate: self,

背景:

public class SendNet: NSObject, GCDAsyncSocketDelegate {

    var socket:GCDAsyncSocket! = nil

    func setupConnection(){

            var error : NSError?
            if (socket == nil) {
                socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
            } else {
                socket.disconnect()
            }


            if (!socket.connectToHost(host, onPort: port, withTimeout: 5.0, error: &error)){
                println("Error: \(error)")
            } else {
                println("Connecting...")
            }
    }

    public func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16) {

       println("Connected to \(host) on port \(p).")

       self.socket = socket

       getSystemInfo()
       getSystemStatus()

    }

    func send(msgBytes: [UInt8]) {

        var msgData = NSData(bytes: msgBytes, length: msgBytes)
        socket.writeData(msgData, withTimeout: -1.0, tag: 0)
        socket.readDataWithTimeout(-1.0, tag: 0)

    }

    func getSystemInfo() {

        var sendBytes:[UInt8] = [0x0, 0x1, 0x2, 0x3]
        send(sendBytes)

    }

    func getSystemStatus() {

        var sendBytes:[UInt8] = [0x4, 0x5, 0x6, 0x7]
        send(sendBytes)

    }


    public func socket(socket : GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int){

         var msgData = NSMutableData()
         msgData.setData(data)

         var msgType:UInt16 = 0
         msgData.getBytes(&msgType, range: NSRange(location: 2,length: 1))

         println(msgType)

      }
}
我在Swift 1.2项目中成功地使用了
GCDAsyncSocket
(通过桥接头)

现在的挑战是它需要某种队列,因为它所连接的系统一次只能处理和返回一个命令

因此,如果它背对背调用方法,例如:

getSystemInfo()
getSystemStatus()
只有
getSystemInfo()。我希望它能够进行背对背的调用,并在控制器完成处理并返回上一个响应后让它们排队和处理——基本上使过程同步

问题:

public class SendNet: NSObject, GCDAsyncSocketDelegate {

    var socket:GCDAsyncSocket! = nil

    func setupConnection(){

            var error : NSError?
            if (socket == nil) {
                socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
            } else {
                socket.disconnect()
            }


            if (!socket.connectToHost(host, onPort: port, withTimeout: 5.0, error: &error)){
                println("Error: \(error)")
            } else {
                println("Connecting...")
            }
    }

    public func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16) {

       println("Connected to \(host) on port \(p).")

       self.socket = socket

       getSystemInfo()
       getSystemStatus()

    }

    func send(msgBytes: [UInt8]) {

        var msgData = NSData(bytes: msgBytes, length: msgBytes)
        socket.writeData(msgData, withTimeout: -1.0, tag: 0)
        socket.readDataWithTimeout(-1.0, tag: 0)

    }

    func getSystemInfo() {

        var sendBytes:[UInt8] = [0x0, 0x1, 0x2, 0x3]
        send(sendBytes)

    }

    func getSystemStatus() {

        var sendBytes:[UInt8] = [0x4, 0x5, 0x6, 0x7]
        send(sendBytes)

    }


    public func socket(socket : GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int){

         var msgData = NSMutableData()
         msgData.setData(data)

         var msgType:UInt16 = 0
         msgData.getBytes(&msgType, range: NSRange(location: 2,length: 1))

         println(msgType)

      }
}
正如您在下面的示例代码中所看到的,
didConnectToHost
delegate callback下,当它连接到控制器时,它会依次调用
getSystemInfo()
,然后
getSystemStatus()
从系统信息中获取结果后,它应该调用
getSystemStatus()

我一直在研究
NSCondition
NSOperation
,甚至是GCD,但我不确定最优雅的方法是什么。我不想再添加一个队列处理器,因为已经有了
GCDAsyncSocket
的队列设置。最好、最优雅的处理方法是什么

伪类代码:

public class SendNet: NSObject, GCDAsyncSocketDelegate {

    var socket:GCDAsyncSocket! = nil

    func setupConnection(){

            var error : NSError?
            if (socket == nil) {
                socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
            } else {
                socket.disconnect()
            }


            if (!socket.connectToHost(host, onPort: port, withTimeout: 5.0, error: &error)){
                println("Error: \(error)")
            } else {
                println("Connecting...")
            }
    }

    public func socket(socket : GCDAsyncSocket, didConnectToHost host:String, port p:UInt16) {

       println("Connected to \(host) on port \(p).")

       self.socket = socket

       getSystemInfo()
       getSystemStatus()

    }

    func send(msgBytes: [UInt8]) {

        var msgData = NSData(bytes: msgBytes, length: msgBytes)
        socket.writeData(msgData, withTimeout: -1.0, tag: 0)
        socket.readDataWithTimeout(-1.0, tag: 0)

    }

    func getSystemInfo() {

        var sendBytes:[UInt8] = [0x0, 0x1, 0x2, 0x3]
        send(sendBytes)

    }

    func getSystemStatus() {

        var sendBytes:[UInt8] = [0x4, 0x5, 0x6, 0x7]
        send(sendBytes)

    }


    public func socket(socket : GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int){

         var msgData = NSMutableData()
         msgData.setData(data)

         var msgType:UInt16 = 0
         msgData.getBytes(&msgType, range: NSRange(location: 2,length: 1))

         println(msgType)

      }
}

任何建议都很好,谢谢

所以我决定使用NSOperation来实现这个

使用以下代码创建了名为SyncRequest.swift的类文件:

import Foundation

class SyncRequest : NSOperation {

 var socket:GCDAsyncSocket! = nil
 var msgData:NSData! = nil

 override var concurrent: Bool {
   return false
 }

 override var asynchronous: Bool {
   return false
 }

 private var _executing: Bool = false
 override var executing: Bool {
    get {
        return _executing
    }
    set {
        if (_executing != newValue) {
            self.willChangeValueForKey("isExecuting")
            _executing = newValue
            self.didChangeValueForKey("isExecuting")
        }
    }
}

private var _finished: Bool = false;
override var finished: Bool {
    get {
        return _finished
    }
    set {
        if (_finished != newValue) {
            self.willChangeValueForKey("isFinished")
            _finished = newValue
            self.didChangeValueForKey("isFinished")
        }
    }
}

/// Complete the operation
func completeOperation() {
    executing = false
    finished  = true
}

override func start() {
    if (cancelled) {
        finished = true
        return
    }

    executing = true

    main()
}


 override func main() -> (){
    println("starting...")

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "didReadData:", name: "DidReadData", object: nil)

    sendData()
}


    func sendData() {
        socket.writeData(msgData, withTimeout: -1.0, tag: 0)
        println("Sending: \(msgData)")
        socket.readDataWithTimeout(-1.0, tag: 0)
    }


    func didReadData(notif: NSNotification) {
        println("Data Received!")

        NSNotificationCenter.defaultCenter().removeObserver(self, name: "DidReadData", object: nil)

        completeOperation()

    }

}
然后,当我需要向控制器发送信息时,我会执行以下操作:

// sync the request to the controller
let queue = NSOperationQueue() // sync request queue
let requestOperation = SyncRequest()
requestOperation.socket = socket // pass the socket  to send through
requestOperation.msgData = msgData // pass the msgData to send
queue.maxConcurrentOperationCount = 1
queue.addOperation(requestOperation)
当数据从处理GCDAsyncSocket的“didReadData”委托的位置传入时,不要忘记发送NSNotification

public func socket(socket : GCDAsyncSocket!, didReadData data:NSData!, withTag tag:Int){

  ...
  NSNotificationCenter.defaultCenter().postNotificationName("DidReadData", object: data)
  ...

}