1 /* 2 * Copyright 2020, 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 17 import GRPC 18 import NIO 19 import FlatBuffers 20 import Logging 21 import Model 22 23 class Greeter: GreeterProvider { 24 25 var hellos: [Message<HelloReply>] = [] 26 27 init() { 28 let names = ["Stranger1", "Stranger2", "Stranger4", "Stranger3", "Stranger5", "Stranger6"] 29 for name in names { 30 var builder = FlatBufferBuilder() 31 let off = builder.create(string: name) 32 let root = HelloReply.createHelloReply(builder, offsetOfMessage: off) 33 builder.finish(offset: root) 34 hellos.append(Message(builder: &builder)) 35 } 36 } 37 38 func SayHello( 39 _ request: Message<HelloRequest>, 40 context: StatusOnlyCallContext 41 ) -> EventLoopFuture<Message<HelloReply>> { 42 let recipient = request.object.name ?? "Stranger" 43 44 var builder = FlatBufferBuilder() 45 let off = builder.create(string: recipient) 46 let root = HelloReply.createHelloReply(builder, offsetOfMessage: off) 47 builder.finish(offset: root) 48 return context.eventLoop.makeSucceededFuture(Message<HelloReply>(builder: &builder)) 49 } 50 51 func SayManyHellos( 52 request: Message<ManyHellosRequest>, 53 context: StreamingResponseCallContext<Message<HelloReply>> 54 ) -> EventLoopFuture<GRPCStatus> { 55 for _ in 0..<Int(request.object.numGreetings) { 56 let index = Int.random(in: 0..<hellos.count) 57 _ = context.sendResponse(hellos[index]) 58 } 59 return context.eventLoop.makeSucceededFuture(.ok) 60 } 61 } 62 63 // Quieten the logs. 64 LoggingSystem.bootstrap { 65 var handler = StreamLogHandler.standardOutput(label: $0) 66 handler.logLevel = .critical 67 return handler 68 } 69 70 let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 71 defer { 72 try! group.syncShutdownGracefully() 73 } 74 75 // Create some configuration for the server: 76 let configuration = Server.Configuration( 77 target: .hostAndPort("localhost", 0), 78 eventLoopGroup: group, 79 serviceProviders: [Greeter()] 80 ) 81 82 // Start the server and print its address once it has started. 83 let server = Server.start(configuration: configuration) 84 server.map { 85 $0.channel.localAddress 86 }.whenSuccess { address in 87 print("server started on port \(address!.port!)") 88 } 89 90 // Wait on the server's `onClose` future to stop the program from exiting. 91 _ = try server.flatMap { 92 $0.onClose 93 }.wait() 94