/* * Copyright 2017, gRPC Authors All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import Foundation import Dispatch import gRPC import Commander // Common flags and options let sslFlag = Flag("ssl", description:"if true, use SSL for connections") func addressOption(_ address:String) -> Option { return Option("address", default:address, description:"address of server") } let portOption = Option("port", default:"8081", description:"port of server") let messageOption = Option("message", default:"Testing 1 2 3", description:"message to send") // Helper function for client actions func buildEchoService(_ ssl:Bool, _ address:String, _ port:String, _ message:String) -> Echo_EchoService { var service : Echo_EchoService if ssl { let certificateURL = URL(fileURLWithPath:"ssl.crt") let certificates = try! String(contentsOf: certificateURL) service = Echo_EchoService(address:address + ":" + port, certificates:certificates, host:"example.com") service.host = "example.com" } else { service = Echo_EchoService(address:address + ":" + port, secure:false) } service.metadata = Metadata(["x-goog-api-key":"YOUR_API_KEY", "x-ios-bundle-identifier":"io.grpc.echo"]) return service } Group { $0.command("serve", sslFlag, addressOption("0.0.0.0"), portOption, description:"Run an echo server.") { (ssl, address, port) in let sem = DispatchSemaphore(value: 0) let echoProvider = EchoProvider() if ssl { print("Starting secure server") let certificateURL = URL(fileURLWithPath:"ssl.crt") let keyURL = URL(fileURLWithPath:"ssl.key") if let echoServer = Echo_EchoServer(address:address + ":" + port, certificateURL:certificateURL, keyURL:keyURL, provider:echoProvider) { echoServer.start() } } else { print("Starting insecure server") let echoServer = Echo_EchoServer(address:address + ":" + port, provider:echoProvider) echoServer.start() } // This blocks to keep the main thread from finishing while the server runs, // but the server never exits. Kill the process to stop it. _ = sem.wait(timeout: DispatchTime.distantFuture) } $0.command("get", sslFlag, addressOption("localhost"), portOption, messageOption, description: "Perform a unary get().") {(ssl, address, port, message) in let service = buildEchoService(ssl, address, port, message) var requestMessage = Echo_EchoRequest() requestMessage.text = message print("Sending: " + requestMessage.text) let responseMessage = try service.get(requestMessage) print("get received: " + responseMessage.text) } $0.command("expand", sslFlag, addressOption("localhost"), portOption, messageOption, description: "Perform a server-streaming expand().") {(ssl, address, port, message) in let service = buildEchoService(ssl, address, port, message) var requestMessage = Echo_EchoRequest() requestMessage.text = message print("Sending: " + requestMessage.text) let sem = DispatchSemaphore(value: 0) let expandCall = try service.expand(requestMessage) {result in print("result \(result)") sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) var running = true while running { do { let responseMessage = try expandCall.receive() print("Received: \(responseMessage.text)") } catch Echo_EchoClientError.endOfStream { print("expand closed") running = false } } } $0.command("collect", sslFlag, addressOption("localhost"), portOption, messageOption, description: "Perform a client-streaming collect().") {(ssl, address, port, message) in let service = buildEchoService(ssl, address, port, message) let sem = DispatchSemaphore(value: 0) let collectCall = try service.collect() {result in print("result \(result)") sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) let parts = message.components(separatedBy:" ") for part in parts { var requestMessage = Echo_EchoRequest() requestMessage.text = part print("Sending: " + part) try collectCall.send(requestMessage) {error in print(error)} sleep(1) } let responseMessage = try collectCall.closeAndReceive() print("Received: \(responseMessage.text)") } $0.command("update", sslFlag, addressOption("localhost"), portOption, messageOption, description: "Perform a bidirectional-streaming update().") {(ssl, address, port, message) in let service = buildEchoService(ssl, address, port, message) let sem = DispatchSemaphore(value: 0) let updateCall = try service.update() {result in print("result \(result)") sem.signal() } _ = sem.wait(timeout: DispatchTime.distantFuture) DispatchQueue.global().async { var running = true while running { do { let responseMessage = try updateCall.receive() print("Received: \(responseMessage.text)") } catch Echo_EchoClientError.endOfStream { print("update closed") sem.signal() running = false } catch (let error) { print("error: \(error)") } } } let parts = message.components(separatedBy:" ") for part in parts { var requestMessage = Echo_EchoRequest() requestMessage.text = part print("Sending: " + requestMessage.text) try updateCall.send(requestMessage) {error in print(error)} sleep(1) } try updateCall.closeSend() _ = sem.wait(timeout: DispatchTime.distantFuture) } }.run()