grpc-helloworld.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. #include <atomic>
  19. #include <grpc++/grpc++.h>
  20. #include <jni.h>
  21. #include "helloworld.grpc.pb.h"
  22. using grpc::Channel;
  23. using grpc::ClientContext;
  24. using grpc::Server;
  25. using grpc::ServerBuilder;
  26. using grpc::ServerContext;
  27. using grpc::Status;
  28. using helloworld::Greeter;
  29. using helloworld::HelloReply;
  30. using helloworld::HelloRequest;
  31. std::atomic<bool> stop_server(false);
  32. // Logic and data behind the server's behavior.
  33. class GreeterServiceImpl final : public Greeter::Service {
  34. Status SayHello(ServerContext* context, const HelloRequest* request,
  35. HelloReply* reply) override {
  36. std::string prefix("Hello ");
  37. reply->set_message(prefix + request->name());
  38. return Status::OK;
  39. }
  40. };
  41. void StartServer(JNIEnv* env, jobject obj, jmethodID is_cancelled_mid,
  42. int port) {
  43. const int host_port_buf_size = 1024;
  44. char host_port[host_port_buf_size];
  45. snprintf(host_port, host_port_buf_size, "0.0.0.0:%d", port);
  46. GreeterServiceImpl service;
  47. ServerBuilder builder;
  48. // Listen on the given address without any authentication mechanism.
  49. builder.AddListeningPort(host_port, grpc::InsecureServerCredentials());
  50. // Register "service" as the instance through which we'll communicate with
  51. // clients. In this case it corresponds to an *synchronous* service.
  52. builder.RegisterService(&service);
  53. // Finally assemble the server.
  54. std::unique_ptr<Server> server(builder.BuildAndStart());
  55. while (!stop_server.load()) {
  56. // Check with the Java code to see if the user has requested the server stop or the app is no
  57. // longer in the foreground.
  58. jboolean is_cancelled = env->CallBooleanMethod(obj, is_cancelled_mid);
  59. if (is_cancelled == JNI_TRUE) {
  60. stop_server = true;
  61. }
  62. }
  63. }
  64. class GreeterClient {
  65. public:
  66. GreeterClient(std::shared_ptr<Channel> channel)
  67. : stub_(Greeter::NewStub(channel)) {}
  68. // Assembles the client's payload, sends it and presents the response back
  69. // from the server.
  70. std::string SayHello(const std::string& user) {
  71. // Data we are sending to the server.
  72. HelloRequest request;
  73. request.set_name(user);
  74. // Container for the data we expect from the server.
  75. HelloReply reply;
  76. // Context for the client. It could be used to convey extra information to
  77. // the server and/or tweak certain RPC behaviors.
  78. ClientContext context;
  79. // The actual RPC.
  80. Status status = stub_->SayHello(&context, request, &reply);
  81. if (status.ok()) {
  82. return reply.message();
  83. } else {
  84. return status.error_message();
  85. }
  86. }
  87. private:
  88. std::unique_ptr<Greeter::Stub> stub_;
  89. };
  90. // Send an RPC and return the response. Invoked from Java code.
  91. extern "C" JNIEXPORT jstring JNICALL
  92. Java_io_grpc_helloworldexample_cpp_HelloworldActivity_sayHello(
  93. JNIEnv* env, jobject obj_unused, jstring host_raw, jint port_raw,
  94. jstring message_raw) {
  95. const char* host_chars = env->GetStringUTFChars(host_raw, (jboolean*)0);
  96. std::string host(host_chars, env->GetStringUTFLength(host_raw));
  97. int port = static_cast<int>(port_raw);
  98. const char* message_chars = env->GetStringUTFChars(message_raw, (jboolean*)0);
  99. std::string message(message_chars, env->GetStringUTFLength(message_raw));
  100. const int host_port_buf_size = 1024;
  101. char host_port[host_port_buf_size];
  102. snprintf(host_port, host_port_buf_size, "%s:%d", host.c_str(), port);
  103. GreeterClient greeter(
  104. grpc::CreateChannel(host_port, grpc::InsecureChannelCredentials()));
  105. std::string reply = greeter.SayHello(message);
  106. return env->NewStringUTF(reply.c_str());
  107. }
  108. // Start the server. Invoked from Java code.
  109. extern "C" JNIEXPORT void JNICALL
  110. Java_io_grpc_helloworldexample_cpp_HelloworldActivity_startServer(
  111. JNIEnv* env, jobject obj_this, jint port_raw) {
  112. int port = static_cast<int>(port_raw);
  113. jclass cls = env->GetObjectClass(obj_this);
  114. jmethodID is_cancelled_mid =
  115. env->GetMethodID(cls, "isRunServerTaskCancelled", "()Z");
  116. stop_server = false;
  117. StartServer(env, obj_this, is_cancelled_mid, port);
  118. }