aboutsummaryrefslogtreecommitdiffhomepage
path: root/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc
diff options
context:
space:
mode:
Diffstat (limited to 'examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc')
-rw-r--r--examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc142
1 files changed, 142 insertions, 0 deletions
diff --git a/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc b/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc
new file mode 100644
index 0000000000..7a31b783c4
--- /dev/null
+++ b/examples/android/helloworld/app/src/main/cpp/grpc-helloworld.cc
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * 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.
+ *
+ */
+
+#include <atomic>
+
+#include <grpc++/grpc++.h>
+#include <jni.h>
+
+#include "helloworld.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::Greeter;
+using helloworld::HelloReply;
+using helloworld::HelloRequest;
+
+std::atomic<bool> stop_server(false);
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void StartServer(JNIEnv* env, jobject obj, jmethodID is_cancelled_mid,
+ int port) {
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "0.0.0.0:%d", port);
+
+ GreeterServiceImpl service;
+ ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(host_port, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ while (!stop_server.load()) {
+ // Check with the Java code to see if the user has requested the server stop or the app is no
+ // longer in the foreground.
+ jboolean is_cancelled = env->CallBooleanMethod(obj, is_cancelled_mid);
+ if (is_cancelled == JNI_TRUE) {
+ stop_server = true;
+ }
+ }
+}
+
+class GreeterClient {
+ public:
+ GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload, sends it and presents the response back
+ // from the server.
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ return status.error_message();
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+// Send an RPC and return the response. Invoked from Java code.
+extern "C" JNIEXPORT jstring JNICALL
+Java_io_grpc_helloworldexample_cpp_HelloworldActivity_sayHello(
+ JNIEnv* env, jobject obj_unused, jstring host_raw, jint port_raw,
+ jstring message_raw) {
+ const char* host_chars = env->GetStringUTFChars(host_raw, (jboolean*)0);
+ std::string host(host_chars, env->GetStringUTFLength(host_raw));
+
+ int port = static_cast<int>(port_raw);
+
+ const char* message_chars = env->GetStringUTFChars(message_raw, (jboolean*)0);
+ std::string message(message_chars, env->GetStringUTFLength(message_raw));
+
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "%s:%d", host.c_str(), port);
+
+ GreeterClient greeter(
+ grpc::CreateChannel(host_port, grpc::InsecureChannelCredentials()));
+ std::string reply = greeter.SayHello(message);
+
+ return env->NewStringUTF(reply.c_str());
+}
+
+// Start the server. Invoked from Java code.
+extern "C" JNIEXPORT void JNICALL
+Java_io_grpc_helloworldexample_cpp_HelloworldActivity_startServer(
+ JNIEnv* env, jobject obj_this, jint port_raw) {
+ int port = static_cast<int>(port_raw);
+
+ jclass cls = env->GetObjectClass(obj_this);
+ jmethodID is_cancelled_mid =
+ env->GetMethodID(cls, "isRunServerTaskCancelled", "()Z");
+
+ stop_server = false;
+
+ StartServer(env, obj_this, is_cancelled_mid, port);
+}