[Review] gRPC ~Ep.2~

## Introduction
I was in need to transfer the huge matrix data from A to B, and initially I was trying to do this by Websockets though, the latency was really bad.
So I have decided to use more sophisticated protocol to communicate with B, which is <font color="red">**gRPC**</font>.
In this article, let me briefly summarise about gRPC and its use-case as well.

Official Document
https://grpc.io/docs/guides/index.html

## Overview
gRPC can use `protocol buffers` as both its Interface Definition Language (IDL) and as its underlying message interchange format.

<img width="682" alt="Screen Shot 2018-07-17 at 17.23.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/240801/0b66865d-3395-d5b2-8826-b29536790ab0.png">
So, simply saying, the interface of client-server is same. So that means, you can programme both components in any kind of programming languages.
But, in order to utilise this function, we should be equipped with the `protocol buffers` more.
So let us move on to learning it.

[Official Page: What are protocol buffers?](https://developers.google.com/protocol-buffers/docs/overview)

## Look Back Previous Section
We learned how to use protocol buffers.
https://qiita.com/Rowing0914/items/bda7661466124f4633e6

So in this volume, let's finish covering the basics of gRPC!

## QuickStart of gRPC
Let's get start learning gRPC!!!
Ops.,,, before you begin, you have to pay attention to their prerequisites written below.

https://grpc.io/docs/quickstart/python.html
1. Make sure your pip version is above 9.0.1. `$ python -m pip install --upgrade pip`
2. Install `grpcio`. `$ python -m pip install grpcio`
3. Install `grpc tools`. `$ python -m pip install grpcio-tools googleapis-common-protos`
4. clone and navigate to the example app as below

```bash
# Clone the repository to get the example code:
$ git clone -b v1.13.x https://github.com/grpc/grpc
# Navigate to the "hello, world" Python example:
$ cd grpc/examples/python/helloworld
```
5. Run the server and client!

```bash
$ python greeter_server.py
$ python greeter_client.py
# output: from client side
# Greeter client received: Hello, you!
```
Congrats on your first trial with gRPC. in next section, let's dig in more and modify the function written in server and client!

## Upgrade a gRPC service
So far, if you look at the distributed file `./grpc/examples/protos/helloworld.proto`, it must look something like this.

```proto
syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
```
For now all you need to know is that both the server and the client “stub” have a SayHello RPC method that takes a HelloRequest parameter from the client and returns a HelloResponse from the server.

```proto
syntax = "proto3";

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
```
Then compile this from python.
`$ python -m grpc_tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto`

phew,,, then let's update server and client side now.

```python:client.py
from __future__ import print_function

import grpc

import helloworld_pb2
import helloworld_pb2_grpc


def run():
    channel = grpc.insecure_channel('localhost:50051')
    stub = helloworld_pb2_grpc.GreeterStub(channel)
    response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
    print("Greeter client received: " + response.message)
    response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='you'))
    print("Greeter client received: " + response.message)


if __name__ == '__main__':
    run()
```

```python:server.py
from concurrent import futures
import time

import grpc

import helloworld_pb2
import helloworld_pb2_grpc

_ONE_DAY_IN_SECONDS = 60 * 60 * 24


class Greeter(helloworld_pb2_grpc.GreeterServicer):

    def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)

    def SayHelloAgain(self, request, context):
        return helloworld_pb2.HelloReply(message='Hello again, %s!' % request.name)


def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port('[::]:50051')
    server.start()
    try:
        while True:
            time.sleep(_ONE_DAY_IN_SECONDS)
    except KeyboardInterrupt:
        server.stop(0)


if __name__ == '__main__':
    serve()
```

<font color="red">*RUN*</font>
![download.jpeg](https://qiita-image-store.s3.amazonaws.com/0/240801/c51a93d6-873a-12bb-4340-fad00fcdd2b4.jpeg)


## outcome from server side
Greeter client received: Hello, you!
Greeter client received: Hello again, you!