grpc netty

gRPC-Javaの仕組みが気になったのでコードリーディングしてみた

https://qiita.com/sugikeitter/items/3291affedc221f117982

gRPC-Javaについて

  • サーバ側では通信制御部分はNettyを利用している
  • クライアント側はAndroidの場合はOkHttp、それ以外はNettyを利用している

 

 

nettyについて

はじめての Netty

https://www.slideshare.net/mikeneck/jjug-ccc-2018-spring-i7-netty

Javaでnon-blocking I/O(以下、NIO)のアプリケーションを作成できるフレームワークである。(Java サーブレットは使わない)

client

<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Google, Inc.
~
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.serviceapl</groupId>
<packaging>pom</packaging>
<version>1.28.1</version>

<artifactId>serviceapl-client</artifactId>
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.1.4</version>
<configuration>
<mainClass>com.example.grpc.serviceapl.ServiceAplClient</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

server

<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 Google, Inc.
~
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.serviceapl</groupId>
<packaging>pom</packaging>
<version>1.28.1</version>

<artifactId>serviceapl-server</artifactId>

<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.28.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>11</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11</version>
</dependency>
</dependencies> <build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration> </plugin>
</plugins>
</build>
</project>

package com.example.grpc.serviceapl;package com.example.grpc.serviceapl;/** * Created by rayt on 5/16/16. */

import io.grpc.stub.StreamObserver;import javafx.application.Platform;import javafx.collections.FXCollections;import javafx.collections.ObservableList;
public class StreamObserverImpl implements StreamObserver<ServiceApl.ServiceAplMessageFromServer> {
private ObservableList<String> messages = FXCollections.observableArrayList();
public StreamObserverImpl(ObservableList<String> messages){ this.messages = messages; } void setMessage(ObservableList<String> messages) { this.messages = messages; }
@Override public void onNext(ServiceApl.ServiceAplMessageFromServer value) { Platform.runLater*1;//           messagesView.scrollTo(messages.size()); }); }
@Override public void onError(Throwable t) { t.printStackTrace(); System.out.println("Disconnected"); }
@Override public void onCompleted() { System.out.println("Disconnected"); }
}

*1:) -> { messages.add(value.getMessage().getFrom() + ": " + value.getMessage().getMessage(

package com.example.grpc.serviceapl;
/**
* Created by rayt on 5/16/16.
*/


import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.StreamObserver;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ServiceAplClient extends Application {
private ObservableList<String> messages = FXCollections.observableArrayList();
private ListView<String> messagesView = new ListView<>();
private TextField name = new TextField("name");
private TextField message = new TextField();
private Button send = new Button();

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
messagesView.setItems(messages);

send.setText("Send");

BorderPane pane = new BorderPane();
pane.setLeft(name);
pane.setCenter(message);
pane.setRight(send);

BorderPane root = new BorderPane();
root.setCenter(messagesView);
root.setBottom(pane);

primaryStage.setTitle("gRPC Sericeapl");
primaryStage.setScene(new Scene(root, 480, 320));

primaryStage.show();

// ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090).usePlaintext(true).build();
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 9090).usePlaintext(true).build();
ServiceAplServiceGrpc.ServiceAplServiceStub stubServiceApl = ServiceAplServiceGrpc.newStub(channel);
StreamObserver<ServiceApl.ServiceAplMessageFromServer> objStreamObserver = new StreamObserverImpl(messages);
StreamObserver<ServiceApl.ServiceAplMessage> objServiceApl = stubServiceApl.serviceApl(objStreamObserver);

/*
StreamObserver<ServiceApl.ServiceAplMessage> objServiceApl = stubServiceApl.serviceApl(new StreamObserver<ServiceApl.ServiceAplMessageFromServer>() {
@Override
public void onNext(ServiceApl.ServiceAplMessageFromServer value) {
Platform.runLater*1;
messagesView.scrollTo(messages.size());
});
}

@Override
public void onError(Throwable t) {
t.printStackTrace();
System.out.println("Disconnected");
}

@Override
public void onCompleted() {
System.out.println("Disconnected");
}
});
* */

send.setOnAction(e -> {
objServiceApl.onNext(ServiceApl.ServiceAplMessage.newBuilder().setFrom(name.getText()).setMessage(message.getText()).build());
message.setText("");
});
primaryStage.setOnCloseRequest(e -> {objServiceApl.onCompleted(); channel.shutdown(); });
}
}

*1:) -> {
messages.add(value.getMessage().getFrom() + ": " + value.getMessage().getMessage(

package com.example.grpc.serviceapl;package com.example.grpc.serviceapl;
import java.util.Set;import java.util.concurrent.ConcurrentHashMap;
import com.example.grpc.serviceapl.ServiceApl.ServiceAplMessage;import com.example.grpc.serviceapl.ServiceApl.ServiceAplMessageFromServer;import com.google.protobuf.Timestamp;import io.grpc.stub.StreamObserver;
import java.util.Collections;import java.util.LinkedHashSet;import java.util.List;
public class StreamObserverServerImpl implements StreamObserver<ServiceApl.ServiceAplMessage> { private StreamObserver<ServiceApl.ServiceAplMessageFromServer> observer = null;
public StreamObserverServerImpl(StreamObserver<ServiceApl.ServiceAplMessageFromServer> observer) { this.observer = observer; }
@Override public void onCompleted() {//       observers.remove(responseObserver); int fldsjk = 0; fldsjk = 30;
}
@Override public void onError(Throwable arg0) { // TODO Auto-generated method stub
}
@Override public void onNext(ServiceAplMessage value) { System.out.println(value); //add message ServiceApl.ServiceAplMessage message2 = ServiceApl.ServiceAplMessage.newBuilder().setFrom(value.getFrom()) .setMessage(value.getMessage()).setServermessage("hello").build(); //set message ServiceApl.ServiceAplMessageFromServer message = ServiceApl.ServiceAplMessageFromServer.newBuilder() .setMessage(message2).setTimestamp(Timestamp.newBuilder().setSeconds(System.currentTimeMillis() / 1000)) .build();
this.observer.onNext(message); }
}