main.swift 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright 2019, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Commander
  17. import Dispatch
  18. import Foundation
  19. import NIO
  20. import SwiftGRPCNIO
  21. // Common flags and options
  22. func addressOption(_ address: String) -> Option<String> {
  23. return Option("address", default: address, description: "address of server")
  24. }
  25. let portOption = Option("port", default: 8080)
  26. let messageOption = Option("message",
  27. default: "Testing 1 2 3",
  28. description: "message to send")
  29. /// Create en `EchoClient` and wait for it to initialize. Returns nil if initialisation fails.
  30. func makeEchoClient(address: String, port: Int) -> Echo_EchoService_NIOClient? {
  31. let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  32. do {
  33. return try GRPCClient.start(host: address, port: port, eventLoopGroup: eventLoopGroup)
  34. .map { client in Echo_EchoService_NIOClient(client: client) }
  35. .wait()
  36. } catch {
  37. print("Unable to create an EchoClient: \(error)")
  38. return nil
  39. }
  40. }
  41. Group {
  42. $0.command("serve",
  43. addressOption("0.0.0.0"),
  44. portOption,
  45. description: "Run an echo server.") { address, port in
  46. let sem = DispatchSemaphore(value: 0)
  47. let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)
  48. print("starting insecure server")
  49. _ = try! GRPCServer.start(hostname: address,
  50. port: port,
  51. eventLoopGroup: eventLoopGroup,
  52. serviceProviders: [EchoProviderNIO()])
  53. .wait()
  54. // This blocks to keep the main thread from finishing while the server runs,
  55. // but the server never exits. Kill the process to stop it.
  56. _ = sem.wait()
  57. }
  58. $0.command(
  59. "get",
  60. addressOption("localhost"),
  61. portOption,
  62. messageOption,
  63. description: "Perform a unary get()."
  64. ) { address, port, message in
  65. print("calling get")
  66. guard let echo = makeEchoClient(address: address, port: port) else { return }
  67. var requestMessage = Echo_EchoRequest()
  68. requestMessage.text = message
  69. print("get sending: \(requestMessage.text)")
  70. let get = echo.get(requestMessage)
  71. get.response.whenSuccess { response in
  72. print("get received: \(response.text)")
  73. }
  74. get.response.whenFailure { error in
  75. print("get response failed with error: \(error)")
  76. }
  77. // wait() on the status to stop the program from exiting.
  78. do {
  79. let status = try get.status.wait()
  80. print("get completed with status: \(status)")
  81. } catch {
  82. print("get status failed with error: \(error)")
  83. }
  84. }
  85. $0.command(
  86. "expand",
  87. addressOption("localhost"),
  88. portOption,
  89. messageOption,
  90. description: "Perform a server-streaming expand()."
  91. ) { address, port, message in
  92. print("calling expand")
  93. guard let echo = makeEchoClient(address: address, port: port) else { return }
  94. let requestMessage = Echo_EchoRequest.with { $0.text = message }
  95. print("expand sending: \(requestMessage.text)")
  96. let expand = echo.expand(requestMessage) { response in
  97. print("expand received: \(response.text)")
  98. }
  99. // wait() on the status to stop the program from exiting.
  100. do {
  101. let status = try expand.status.wait()
  102. print("expand completed with status: \(status)")
  103. } catch {
  104. print("expand status failed with error: \(error)")
  105. }
  106. }
  107. $0.command(
  108. "collect",
  109. addressOption("localhost"),
  110. portOption,
  111. messageOption,
  112. description: "Perform a client-streaming collect()."
  113. ) { address, port, message in
  114. print("calling collect")
  115. guard let echo = makeEchoClient(address: address, port: port) else { return }
  116. let collect = echo.collect()
  117. var queue = collect.newMessageQueue()
  118. for part in message.components(separatedBy: " ") {
  119. var requestMessage = Echo_EchoRequest()
  120. requestMessage.text = part
  121. print("collect sending: \(requestMessage.text)")
  122. queue = queue.then { collect.sendMessage(requestMessage) }
  123. }
  124. queue.whenSuccess { collect.sendEnd(promise: nil) }
  125. collect.response.whenSuccess { respone in
  126. print("collect received: \(respone.text)")
  127. }
  128. collect.response.whenFailure { error in
  129. print("collect response failed with error: \(error)")
  130. }
  131. // wait() on the status to stop the program from exiting.
  132. do {
  133. let status = try collect.status.wait()
  134. print("collect completed with status: \(status)")
  135. } catch {
  136. print("collect status failed with error: \(error)")
  137. }
  138. }
  139. $0.command(
  140. "update",
  141. addressOption("localhost"),
  142. portOption,
  143. messageOption,
  144. description: "Perform a bidirectional-streaming update()."
  145. ) { address, port, message in
  146. print("calling update")
  147. guard let echo = makeEchoClient(address: address, port: port) else { return }
  148. let update = echo.update { response in
  149. print("update received: \(response.text)")
  150. }
  151. var queue = update.newMessageQueue()
  152. for part in message.components(separatedBy: " ") {
  153. var requestMessage = Echo_EchoRequest()
  154. requestMessage.text = part
  155. print("update sending: \(requestMessage.text)")
  156. queue = queue.then { update.sendMessage(requestMessage) }
  157. }
  158. queue.whenSuccess { update.sendEnd(promise: nil) }
  159. // wait() on the status to stop the program from exiting.
  160. do {
  161. let status = try update.status.wait()
  162. print("update completed with status: \(status)")
  163. } catch {
  164. print("update status failed with error: \(error)")
  165. }
  166. }
  167. }.run()