1/* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19#import "ViewController.h" 20#import <grpcpp/grpcpp.h> 21 22#include <grpcpp/generic/async_generic_service.h> 23#include <grpcpp/generic/generic_stub.h> 24 25static void* tag(int i) { return (void*)(intptr_t)i; } 26 27// Serialized Proto bytes of Hello World example 28const uint8_t kMessage[] = {0x0A, 0x0B, 0x4F, 0x62, 0x6A, 0x65, 0x63, 29 0x74, 0x69, 0x76, 0x65, 0x2D, 0x43}; 30 31@interface ViewController () 32 33@end 34 35@implementation ViewController { 36 grpc::CompletionQueue cq_; 37 std::unique_ptr<grpc::GenericStub> generic_stub_; 38} 39 40- (void)viewDidLoad { 41 [super viewDidLoad]; 42 43 // Setup call stub 44 std::shared_ptr<grpc::Channel> channel = 45 CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); 46 generic_stub_.reset(new grpc::GenericStub(channel)); 47 48 const std::string kMethodName("/helloworld.Greeter/SayHello"); 49 void* got_tag; 50 bool ok; 51 52 grpc::ClientContext cli_ctx; 53 std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call = 54 generic_stub_->Call(&cli_ctx, kMethodName, &cq_, tag(1)); 55 cq_.Next(&got_tag, &ok); 56 if (!ok || got_tag != tag(1)) { 57 NSLog(@"Failed to create call."); 58 abort(); 59 } 60 grpc::Slice send_slice = grpc::Slice(kMessage, sizeof(kMessage) / sizeof(kMessage[0])); 61 std::unique_ptr<grpc::ByteBuffer> send_buffer(new grpc::ByteBuffer(&send_slice, 1)); 62 call->Write(*send_buffer, tag(2)); 63 cq_.Next(&got_tag, &ok); 64 if (!ok || got_tag != tag(2)) { 65 NSLog(@"Failed to send message."); 66 abort(); 67 } 68 grpc::ByteBuffer recv_buffer; 69 call->Read(&recv_buffer, tag(3)); 70 cq_.Next(&got_tag, &ok); 71 if (!ok || got_tag != tag(3)) { 72 NSLog(@"Failed to receive message."); 73 abort(); 74 } 75 76 grpc::Status status; 77 call->Finish(&status, tag(4)); 78 cq_.Next(&got_tag, &ok); 79 if (!ok || got_tag != tag(4)) { 80 NSLog(@"Failed to finish call."); 81 abort(); 82 } 83 if (!status.ok()) { 84 NSLog(@"Received unsuccessful status code: %d", status.error_code()); 85 abort(); 86 } 87 std::vector<grpc::Slice> slices; 88 recv_buffer.Dump(&slices); 89 NSString* recvBytes = [[NSString alloc] init]; 90 for (auto slice : slices) { 91 auto p = slice.begin(); 92 while (p != slice.end()) { 93 recvBytes = [recvBytes stringByAppendingString:[NSString stringWithFormat:@"%02x ", *p]]; 94 p++; 95 } 96 } 97 NSLog(@"Hello World succeeded.\nReceived bytes: %@\n" 98 "Expected bytes: 0a 11 48 65 6c 6c 6f 20 4f 62 6a 65 63 74 69 76 65 2d 43", 99 recvBytes); 100} 101 102@end 103