Dans cet article, j'ai décidé d'utiliser gRPC pour la communication entre le serveur et le client dans le projet sur lequel je travaille actuellement, et j'ai écrit que j'ai fait beaucoup de recherches tout en faisant un tutoriel pour implémenter gRPC sur Android. ..
Qu'est-ce que gRPC? Comme mentionné dans l'aperçu, il s'agit d'un protocole de communication développé par Google. [Appel de procédure à distance](https://ja.wikipedia.org/wiki/%E9%81%A0%E9%9A%94%E6%89%8B%E7%B6%9A%E3%81%8D%E5 % 91% BC% E5% 87% BA% E3% 81% 97) a été développé pour réaliser une technologie qui permet au serveur et au client de communiquer en appelant directement la méthode serveur, et vice versa. J'ai fait.
Dans l'API REST conventionnelle, les informations étaient principalement échangées avec Json, mais comme le serveur et le client implémentent séparément, le coût de mise en œuvre a augmenté.
Cependant, gRPC peut générer des implémentations de divers langages de programmation simplement en définissant les spécifications d'API dans le fichier .proto
, ce qui conduit à une réduction des coûts d'implémentation sur le serveur et le client.
De plus, Protocol Buffers permet une communication plus rapide que REST. [^ 1] [^ 2]
Hello World
Tout d'abord, en regardant le Guide de démarrage rapide officiel, je vais essayer de déplacer l'application qui renvoie Hello 〇 〇 (chaîne de caractères d'entrée arbitraire).
Téléchargez l'exemple de code depuis le référentiel Github avec git clone
.
$ # 2017/12/22 Dernière version 1.8.Télécharger 0
$ git clone -b v1.8.0 https://github.com/grpc/grpc-java
$ #Déplacer vers le répertoire contenant l'exemple de code
$ cd grpc-java/examples
Dans le répertoire grpc-java / examples
, compilez le serveur en procédant comme suit:
$ ./gradlew installDist
Ensuite, laissez le serveur fonctionner.
$ ./build/install/examples/bin/hello-world-server
Connectez votre appareil Android en mode débogage et exécutez ce qui suit dans adb.
adb reverse tcp:8080 tcp:50051
Ouvrez un terminal différent de celui sur lequel vous avez exécuté le serveur, puis compilez et exécutez le client.
$ cd android/helloworld
$ ./gradlew installDebug
En cas de succès, l'application sera installée sur votre appareil et vous devriez voir un écran comme celui ci-dessous.
Entrez localhost
dans Host, 8080
dans Port (car il a été inversé en 50051 avec adb), entrez le caractère que vous souhaitez envoyer de manière appropriée dans le message (par exemple, world
), et la réponse est renvoyée comme suit. Quand il s'agit, la communication avec le serveur est réussie!
Cela a fonctionné pour le moment, mais quel est le contenu réel du code?
Regardons maintenant le fichier .proto
, le code serveur et le code client (Android).
helloworld.proto
et code généré//Définition de la méthode
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
//Définition de la structure des données de demande
message HelloRequest {
string name = 1;
}
//Définition de la structure des données de réponse
message HelloReply {
string message = 1;
}
Dans le fichier helloworld.proto
, écrivez les spécifications de l'API comme décrit ci-dessus.
Plus précisément, décrivez la méthode et la structure de données des données à utiliser.
Pour plus d'informations sur l'écriture, consultez le Guide linguistique (proto3) dans Protocol Buffers. Voir buffers / docs / proto3? Hl = ja).
La compilation de ce fichier helloworld.proto
pour chaque langue générera une interface gRPC spécifique à la langue.
En ce qui concerne le côté serveur, il est écrit dans l'article J'ai essayé gRPC maintenant, donc je vais l'omettre ici.
helloworld.proto
Le code généré à partir de helloworld.proto
est construit avec gradlew
et placé à l'emplacement suivant dans le répertoire ʻapp / build / generated`:
Le code implémenté sous forme d'exemple ressemble à ce qui suit. (Partiellement omis)
Au fait, comme OnClickListener n'est pas implémenté, je cherchais sans savoir comment appeler la méthode sendMessage, mais il semble qu'elle soit appelée à partir du layout xml.
HelloworldActivity.java
public class HelloworldActivity extends AppCompatActivity {
...
public void sendMessage(View view) {
new GrpcTask().execute();
}
private class GrpcTask extends AsyncTask<Void, Void, String> {
private String mHost;
private String mMessage;
private int mPort;
private ManagedChannel mChannel;
@Override
protected void onPreExecute() {
mHost = mHostEdit.getText().toString();
mMessage = mMessageEdit.getText().toString();
String portStr = mPortEdit.getText().toString();
mPort = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr);
mResultText.setText("");
}
@Override
protected String doInBackground(Void... nothing) {
try {
//Créer une chaîne
mChannel = ManagedChannelBuilder.forAddress(mHost, mPort)
.usePlaintext(true)
.build();
//Créer un stub
GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(mChannel);
//Créer une demande et spécifier la valeur
HelloRequest message = HelloRequest.newBuilder().setName(mMessage).build();
//Exécutez la méthode sayHello et recevez une réponse
HelloReply reply = stub.sayHello(message);
return reply.getMessage();
} catch (Exception e) {
...
}
}
@Override
protected void onPostExecute(String result) {
try {
mChannel.shutdown().awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
mResultText.setText(result);
}
}
}
Comme la communication doit être implémentée en tant que traitement asynchrone, nous créons une classe GrpcTask qui hérite d'AsyncTask.
En regardant à l'intérieur de la méthode doInBackground qui effectue un traitement asynchrone,
Vous pouvez voir qu'il est possible de réaliser le processus de communication et de retour de réponse simplement en spécifiant request comme argument de la méthode sayHello de la même manière que l'appel de la méthode de la classe. ..
Lorsque j'ai touché gRPC pour la première fois cette fois, j'ai senti qu'il pouvait être implémenté beaucoup plus simplement que REST. J'étais très reconnaissant de pouvoir écrire intuitivement la partie communication sous forme de méthode.
Dans le futur, j'aimerais approfondir ma compréhension tout en l'implémentant dans le projet.