Bladeren bron

Update Echo Mac app to use new Service API prototype.

Tim Burks 9 jaren geleden
bovenliggende
commit
fd73a4e5b3

+ 130 - 50
Examples/Echo/Swift/Echo/EchoService.swift

@@ -36,16 +36,17 @@ import gRPC
 // all code that follows is to-be-generated
 
 enum EchoResult {
-  case Success(r: Echo_EchoResponse)
-  case Error(e: CallResult)
+  case Response(r: Echo_EchoResponse)
+  // these last two should be merged
+  case CallResult(c: CallResult)
+  case Error(s: String)
 }
 
-
 public class EchoGetCall {
   var call : Call
 
-  init(_ call: Call) {
-    self.call = call
+  init(_ channel: Channel) {
+    self.call = channel.makeCall("/echo.Echo/Get")
   }
 
   // Call this with the message to send,
@@ -61,9 +62,9 @@ public class EchoGetCall {
         print("Client received status \(callResult.statusCode) \(callResult.statusMessage!)")
         if let messageData = callResult.resultData {
           let responseMessage = try! Echo_EchoResponse(protobuf:messageData)
-          callback(EchoResult.Success(r: responseMessage))
+          callback(EchoResult.Response(r: responseMessage))
         } else {
-          callback(EchoResult.Error(e: callResult))
+          callback(EchoResult.CallResult(c: callResult))
         }
       }
   }
@@ -72,47 +73,53 @@ public class EchoGetCall {
 public class EchoExpandCall {
   var call : Call
 
-  init(_ call: Call) {
-    self.call = call
+  init(_ channel: Channel) {
+    self.call = channel.makeCall("/echo.Echo/Expand")
   }
 
   // Call this once with the message to send,
   // the callback will be called after the request is initiated.
   func perform(request: Echo_EchoRequest,
-               callback:@escaping (CallResult, Echo_EchoResponse?) -> Void)
+               callback:@escaping (CallResult) -> Void)
     -> Void {
       let requestMessageData = try! request.serializeProtobuf()
       let requestMetadata = Metadata()
       try! call.startServerStreaming(message: requestMessageData,
                                      metadata: requestMetadata)
       {(callResult) in
-        //print("Client received status \(callResult.statusCode): \(callResult.statusMessage!)")
+        callback(callResult)
       }
   }
 
-  // Call this to receive a message.
-  // The callback will be called when a message is received.
-  // call this again from the callback to wait for another message.
-  func receiveMessage(callback:@escaping (Echo_EchoResponse?) throws -> Void) throws {
-    try call.receiveMessage() {(data) in
+  func Recv() -> EchoResult {
+    let done = NSCondition()
+    var result : EchoResult!
+    try! call.receiveMessage() {(data) in
       if let data = data {
         if let responseMessage = try? Echo_EchoResponse(protobuf:data) {
-          try callback(responseMessage)
+          result = EchoResult.Response(r: responseMessage)
         } else {
-          try callback(nil)
+          result = EchoResult.Error(s: "INVALID RESPONSE")
         }
       } else {
-        try callback(nil)
+        result = EchoResult.Error(s: "EOM")
       }
+      done.lock()
+      done.signal()
+      done.unlock()
     }
+    done.lock()
+    done.wait()
+    done.unlock()
+    return result
   }
 }
 
 public class EchoCollectCall {
   var call : Call
 
-  init(_ call: Call) {
-    self.call = call
+  init(_ channel: Channel) {
+    self.call = channel.makeCall("/echo.Echo/Collect")
   }
 
   // Call this to start a call.
@@ -121,17 +128,54 @@ public class EchoCollectCall {
   }
 
   // Call this to send each message in the request stream.
-  func sendMessage(message: Echo_EchoRequest) {
+  func Send(_ message: Echo_EchoRequest) {
     let messageData = try! message.serializeProtobuf()
     _ = call.sendMessage(data:messageData)
   }
 
+  func CloseAndRecv() -> EchoResult {
+    let done = NSCondition()
+    var result : EchoResult!
+
+    do {
+      try self.receiveMessage() {(responseMessage) in
+        if let responseMessage = responseMessage {
+          result = EchoResult.Response(r: responseMessage)
+        } else {
+          result = EchoResult.Error(s: "INVALID RESPONSE")
+        }
+        done.lock()
+        done.signal()
+        done.unlock()
+      }
+    } catch (let error) {
+      print("ERROR A: \(error)")
+    }
+    do {
+      try call.close(completion:{
+        print("closed")
+      })
+    } catch (let error) {
+      print("ERROR B: \(error)")
+    }
+
+    done.lock()
+    done.wait()
+    done.unlock()
+
+    return result
+  }
+
   // Call this to receive a message.
   // The callback will be called when a message is received.
   // call this again from the callback to wait for another message.
   func receiveMessage(callback:@escaping (Echo_EchoResponse?) throws -> Void)
     throws {
       try call.receiveMessage() {(data) in
+        guard let data = data else {
+          try callback(nil)
+          return
+        }
         guard
           let responseMessage = try? Echo_EchoResponse(protobuf:data)
           else {
@@ -141,17 +185,13 @@ public class EchoCollectCall {
       }
   }
 
-
-  func close(completion:@escaping (() -> Void)) throws {
-    try call.close(completion:completion)
-  }
 }
 
 public class EchoUpdateCall {
   var call : Call
 
-  init(_ call: Call) {
-    self.call = call
+  init(_ channel: Channel) {
+    self.call = channel.makeCall("/echo.Echo/Update")
   }
 
   func start(metadata:Metadata, completion:@escaping (() -> Void)) throws {
@@ -160,26 +200,52 @@ public class EchoUpdateCall {
 
   func receiveMessage(callback:@escaping (Echo_EchoResponse?) throws -> Void) throws {
     try call.receiveMessage() {(data) in
-      guard let data = data
-        else {
-          return
+      if let data = data {
+        if let responseMessage = try? Echo_EchoResponse(protobuf:data) {
+          try callback(responseMessage)
+        } else {
+          try callback(nil) // error, bad data
+        }
+      } else {
+        try callback(nil)
       }
-      guard
-        let responseMessage = try? Echo_EchoResponse(protobuf:data)
-        else {
-          return
+    }
+  }
+
+  func Recv() -> EchoResult {
+    let done = NSCondition()
+    var result : EchoResult!
+    try! self.receiveMessage() {responseMessage in
+      if let responseMessage = responseMessage {
+        result = EchoResult.Response(r: responseMessage)
+      } else {
+        result = EchoResult.Error(s: "EOM")
       }
-      try callback(responseMessage)
+      done.lock()
+      done.signal()
+      done.unlock()
     }
+    done.lock()
+    done.wait()
+    done.unlock()
+    return result
   }
 
-  func sendMessage(message: Echo_EchoRequest) {
+  func Send(message:Echo_EchoRequest) {
     let messageData = try! message.serializeProtobuf()
     _ = call.sendMessage(data:messageData)
   }
 
-  func close(completion:@escaping (() -> Void)) throws {
-    try call.close(completion:completion)
+  func CloseSend() {
+    let done = NSCondition()
+    try! call.close() {
+      done.lock()
+      done.signal()
+      done.unlock()
+    }
+    done.lock()
+    done.wait()
+    done.unlock()
   }
 }
 
@@ -194,24 +260,38 @@ public class EchoService {
     channel = Channel(address:address, certificates:certificates, host:host)
   }
 
-  func get(_ requestMessage: Echo_EchoRequest,
-           _ completion:@escaping (EchoResult) -> Void) {
-      let call = EchoGetCall(channel.makeCall("/echo.Echo/Get"))
-      call.perform(request:requestMessage) {(result) in
-        let call = call // retain until completion
-        completion(result)
-      }
+  func get(_ requestMessage: Echo_EchoRequest) -> EchoResult {
+    let call = EchoGetCall(channel)
+
+    let done = NSCondition()
+    var finalResult : EchoResult!
+    call.perform(request:requestMessage) {(result) in
+      finalResult = result
+      done.lock()
+      done.signal()
+      done.unlock()
+    }
+    done.lock()
+    done.wait()
+    done.unlock()
+    return finalResult
   }
 
-  func expand() -> EchoExpandCall {
-    return EchoExpandCall(channel.makeCall("/echo.Echo/Expand"))
+  func expand(_ requestMessage: Echo_EchoRequest) -> EchoExpandCall {
+    let call = EchoExpandCall(channel)
+    call.perform(request:requestMessage) {response in }
+    return call
   }
 
   func collect() -> EchoCollectCall {
-    return EchoCollectCall(channel.makeCall("/echo.Echo/Collect"))
+    let call = EchoCollectCall(channel)
+    try! call.start(metadata:Metadata(), completion:{})
+    return call
   }
 
   func update() -> EchoUpdateCall {
-    return EchoUpdateCall(channel.makeCall("/echo.Echo/Update"))
+    let call = EchoUpdateCall(channel)
+    try! call.start(metadata:Metadata(), completion:{})
+    return call
   }
 }

+ 54 - 45
Examples/Echo/Swift/Echo/EchoViewController.swift

@@ -144,13 +144,14 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         requestMessage.text = self.messageField.stringValue
 
         DispatchQueue.global().async {
-          service.get(requestMessage) { result in
-            switch result {
-            case .Success(let responseMessage):
-              self.displayMessageReceived(responseMessage.text)
-            case .Error(let error):
-              self.displayMessageReceived("No message received. \(error)")
-            }
+          let result = service.get(requestMessage)
+          switch result {
+          case .Response(let responseMessage):
+            self.displayMessageReceived(responseMessage.text)
+          case .CallResult(let result):
+            self.displayMessageReceived("No message received. \(result)")
+          case .Error(let error):
+            self.displayMessageReceived("No message received. \(error)")
           }
         }
       }
@@ -161,12 +162,10 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
         guard let service = service else {
           return
         }
-        expandCall = service.expand()
         var requestMessage = Echo_EchoRequest()
         requestMessage.text = self.messageField.stringValue
+        self.expandCall = service.expand(requestMessage)
         self.displayMessageSent(requestMessage.text)
-        try expandCall!.perform(request:requestMessage) {(callResult, response) in
-        }
         try! self.receiveExpandMessage()
       }
     }
@@ -177,11 +176,6 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
           return
         }
         collectCall = service.collect()
-        try collectCall!.start(metadata:requestMetadata) {
-          // this is called when the server closes the connection
-          print("collect closed")
-        }
-        try self.receiveCollectMessage()
         nowStreaming = true
         closeButton.isEnabled = true
       }
@@ -194,10 +188,6 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
           return
         }
         updateCall = service.update()
-        try updateCall!.start(metadata:requestMetadata) {
-          // this is called when the server closes the connection
-          print("update closed")
-        }
         try self.receiveUpdateMessage()
         nowStreaming = true
         closeButton.isEnabled = true
@@ -210,12 +200,20 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     guard let expandCall = expandCall else {
       return
     }
-    try expandCall.receiveMessage() {(responseMessage) in
-      if let responseMessage = responseMessage {
-        try self.receiveExpandMessage() // prepare to receive the next message
-        self.displayMessageReceived(responseMessage.text)
-      } else {
-        print("expand closed")
+    DispatchQueue.global().async {
+      var running = true
+      while running {
+        let result = expandCall.Recv()
+        switch result {
+        case .Response(let responseMessage):
+          self.displayMessageReceived(responseMessage.text)
+        case .CallResult(let result):
+          self.displayMessageReceived("No message received. \(result)")
+          running = false
+        case .Error(let error):
+          self.displayMessageReceived("No message received. \(error)")
+          running = false
+        }
       }
     }
   }
@@ -225,7 +223,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
       var requestMessage = Echo_EchoRequest()
       requestMessage.text = self.messageField.stringValue
       self.displayMessageSent(requestMessage.text)
-      _ = collectCall.sendMessage(message:requestMessage)
+      _ = collectCall.Send(requestMessage)
     }
   }
 
@@ -249,7 +247,7 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
       var requestMessage = Echo_EchoRequest()
       requestMessage.text = self.messageField.stringValue
       self.displayMessageSent(requestMessage.text)
-      _ = updateCall.sendMessage(message:requestMessage)
+      _ = updateCall.Send(message:requestMessage)
     }
   }
 
@@ -257,34 +255,45 @@ class EchoViewController : NSViewController, NSTextFieldDelegate {
     guard let updateCall = updateCall else {
       return
     }
-    try updateCall.receiveMessage() {(responseMessage) in
-      try self.receiveUpdateMessage() // prepare to receive the next message
-      if let responseMessage = responseMessage {
-        DispatchQueue.main.async {
-          self.receivedOutputField.stringValue = responseMessage.text
+    DispatchQueue.global().async {
+      var running = true
+      while running {
+        let result = updateCall.Recv()
+        switch result {
+        case .Response(let responseMessage):
+          self.displayMessageReceived(responseMessage.text)
+        case .CallResult(let result):
+          self.displayMessageReceived("No message received. \(result)")
+          running = false
+        case .Error(let error):
+          self.displayMessageReceived("No message received. \(error)")
+          running = false
         }
-      } else {
-        print("update closed")
-        self.nowStreaming = false
-        self.closeButton.isEnabled = false
       }
+
     }
   }
 
   func sendClose() throws {
     if let updateCall = updateCall {
-      try updateCall.close() {
-        self.updateCall = nil
-        self.nowStreaming = false
-        self.closeButton.isEnabled = false
-      }
+      updateCall.CloseSend()
+      self.updateCall = nil
+      self.nowStreaming = false
+      self.closeButton.isEnabled = false
     }
     if let collectCall = collectCall {
-      try collectCall.close() {
-        self.collectCall = nil
-        self.nowStreaming = false
-        self.closeButton.isEnabled = false
+      let result = collectCall.CloseAndRecv()
+      switch result {
+      case .Response(let responseMessage):
+        self.displayMessageReceived(responseMessage.text)
+      case .CallResult(let result):
+        self.displayMessageReceived("No message received. \(result)")
+      case .Error(let error):
+        self.displayMessageReceived("No message received. \(error)")
       }
+      self.collectCall = nil
+      self.nowStreaming = false
+      self.closeButton.isEnabled = false
     }
   }
 }

+ 26 - 11
Samples/Echo-v2/Sources/EchoService.swift

@@ -137,21 +137,32 @@ public class EchoCollectCall {
     let done = NSCondition()
     var result : EchoResult!
 
-    try! self.receiveMessage() {(responseMessage) in
-      if let responseMessage = responseMessage {
-        result = EchoResult.Response(r: responseMessage)
-      } else {
-        result = EchoResult.Error(s: "INVALID RESPONSE")
+    do {
+      try self.receiveMessage() {(responseMessage) in
+        if let responseMessage = responseMessage {
+          result = EchoResult.Response(r: responseMessage)
+        } else {
+          result = EchoResult.Error(s: "INVALID RESPONSE")
+        }
+        done.lock()
+        done.signal()
+        done.unlock()
       }
-      done.lock()
-      done.signal()
-      done.unlock()
+    } catch (let error) {
+      print("ERROR A: \(error)")
+    }
+    do {
+      try call.close(completion:{
+        print("closed")
+      })
+    } catch (let error) {
+      print("ERROR B: \(error)")
     }
 
-    try! call.close(completion:{})
     done.lock()
     done.wait()
     done.unlock()
+
     return result
   }
 
@@ -161,6 +172,10 @@ public class EchoCollectCall {
   func receiveMessage(callback:@escaping (Echo_EchoResponse?) throws -> Void)
     throws {
       try call.receiveMessage() {(data) in
+        guard let data = data else {
+          try callback(nil)
+          return
+        }
         guard
           let responseMessage = try? Echo_EchoResponse(protobuf:data)
           else {
@@ -192,7 +207,7 @@ public class EchoUpdateCall {
           try callback(nil) // error, bad data
         }
       } else {
-          try callback(nil)
+        try callback(nil)
       }
     }
   }
@@ -247,7 +262,7 @@ public class EchoService {
 
   func get(_ requestMessage: Echo_EchoRequest) -> EchoResult {
     let call = EchoGetCall(channel)
-    
+
     let done = NSCondition()
     var finalResult : EchoResult!
     call.perform(request:requestMessage) {(result) in