Ich werde darüber schreiben, wie gRPC für die Kommunikation zwischen dem Go API-Server und dem Dart-Client verwendet wird (unter der Annahme von Flutter).
Entwicklung der Haniya Music Festival Osanpo App 2020 hinter den Kulissen / Server Edition DeNAs 20 neue Absolventen und 21 Absolventen Ich habe auf den Artikel der Person verwiesen, also werde ich ihn teilen.
Der Grund, warum ich gerne gRPC verwende, ist die Sitzung von Herrn Nao Minami von den Cloud Native Days Tokyo 2020 "Migration der realen Welt von HTTP zu gRPC". Es ist leicht zu verstehen, wenn Sie zuhören, also werde ich dies auch teilen. Sie können über den Link zum archivierten Video springen.
Um automatisch aus einer .proto-Datei zu generieren, müssen Sie den Befehl protoc und die Peripherie-Plug-Ins verwenden, aber ich möchte verschiedene Dinge nicht lokal installieren, also starte ich einen Docker-Container und generiere Code für jede Sprache. Sie können die neueste Version der aktuellen Protokollpuffer im GitHub-Repository (https://github.com/protocolbuffers/protobuf/releases) überprüfen.
Dockerfile
FROM golang:1.15.0
ENV DEBIAN_FRONTEND=noninteractive
ARG PROTO_VERSION=3.13.0
WORKDIR /proto
COPY ./proto .
RUN mkdir /output /output/server /output/client
RUN apt-get -qq update && apt-get -qq install -y \
unzip
RUN curl -sSL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTO_VERSION}/protoc-${PROTO_VERSION}-linux-x86_64.zip -o protoc.zip && \
unzip -qq protoc.zip && \
cp ./bin/protoc /usr/local/bin/protoc && \
cp -r ./include /usr/local
# Go
RUN go get -u github.com/golang/protobuf/protoc-gen-go
# Dart
RUN apt-get install apt-transport-https
RUN sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
RUN sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
RUN apt-get update
RUN apt-get install dart -y
ENV PATH="${PATH}:/usr/lib/dart/bin/"
ENV PATH="${PATH}:/root/.pub-cache/bin"
RUN pub global activate protoc_plugin
Führen Sie das folgende Skript in diesem Container aus
protoc.sh
#!/bin/sh
set -xe
SERVER_OUTPUT_DIR=/output/server
CLIENT_OUTPUT_DIR=/output/client
protoc --version
protoc -I=/proto/protos hoge.proto fuga.proto\
--go_out=plugins="grpc:${SERVER_OUTPUT_DIR}" \
--dart_out="grpc:${CLIENT_OUTPUT_DIR}"
#Zeitstempel in der Protodatei.Erforderlich beim Importieren von Proto usw.
protoc -I=/proto/protos timestamp.proto wrappers.proto\
--dart_out="grpc:${CLIENT_OUTPUT_DIR}"
Wenn Sie bei Verwendung von Docker-Compose den Befehl festlegen, protoc.sh früher auszuführen, wird der Code beim Start automatisch generiert. Synchronisieren Sie das Verzeichnis mit der Protodatei und protoc.sh mit den Volumes, dem Ausgabeverzeichnis auf der Serverseite und dem Ausgabeverzeichnis auf der Clientseite.
docker-compose.yml
version: '3.8'
services:
proto:
build:
context: .
dockerfile: docker/proto/Dockerfile
command: ./protoc.sh
volumes:
- ./proto:/proto
- ./client:/output/client
- ./server:/output/server
Wenn Sie jedoch beispielsweise das go-Paket auf der Seite der Protodatei angeben
hoge.proto
syntax = "proto3";
package hoge.hoge;
option go_package = "hoge/fuga/foo/bar";
service Hoge{
}
In diesem Fall wird es auf der Containerseite an `` `/ output / server / hoge / fuga / foo``` ausgegeben.
`` `hoge.pb.go``` wird in den in docker-compose.yml angegebenen Volumes generiert. Da die Inerface-Definition von Clinet darin enthalten ist (es ist leicht zu finden, wenn Sie mit ctx in der Datei suchen), implementieren wir die Methode anhand dieses Teils.
go:hoge.pb.go
// HogeClient is the client API for Hoge service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type HogeClient interface {
CreateHoge(ctx context.Context, in *CreateHogeMessage, opts ...grpc.CallOption) (*CreateHogeResponse, error)
}
Erstellen Sie HogeController als Klasse, die HogeClient implementiert. Hierbei ist zu beachten, dass das Argument mit variabler Länge nach dem dritten Argument empfangen wird, es jedoch nicht erforderlich ist, Optionen in die Methode auf der Implementierungsseite zu schreiben.
hoge_controller.go
type HogeController struct{
}
func (ctrl HogeController) CreateHoge(ctx context.Context, in *CreateHogeMessage) (*CreateHogeResponse, error){
// TODO: return *CreateHogeResponse, error
}
Registrieren Sie die oben erstellte HogeController-Instanz bei der gRPC-Serverinstanz bei RegisterHogeServer ().
main.go
func main() {
listenPort, err := net.Listen("tcp", ":8000")
if err != nil {
log.Fatalln(err)
}
server := grpc.NewServer()
hogeCtrl := NewHogeController()
pb.RegisterHogeServer(server, &hogeCtrl)
if err := server.Serve(listenPort); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
Der Client ist `hoge.pb.dart```,`
hoge.pbgrpc.dart, `` `hoge.pbjson.dart
,` `` hoge. Wenn Sie enum verwenden. pbenum.dart``` wird generiert.
Wenn Sie timestamp.dart auf der Seite der Protodatei verwenden, tritt ein Fehler im generierten Pfad auf. Ändern Sie daher einfach die Importanweisung in `hoge.pb.dart``` in`
import'timestamp.pb.dart '. Sie können es verwenden, indem Sie es wie folgt ändern: $ 1; `` `. Bei unären Anrufen können Sie mit den folgenden Funktionen kommunizieren.
hoge.dart
Future<void> createHoge(dartSideParam1, dartSideParam2, dartSideParam3) async {
final channel = ClientChannel('localhost',
port: 8000,
options:
const ChannelOptions(credentials: ChannelCredentials.insecure()));
final grpcClient = KitchenClient(channel,
options: CallOptions(timeout: Duration(seconds: 10)));
try {
await grpcClient.createHoge(CreateHogerMessage()
..param1 = dartSideParam1
..param2 = dartSideParam2
..param3 = dartSideParam3;
await channel.shutdown();
} catch (error) {
developer.log('Caught error: $error');
await channel.shutdown();
return Future.error(error);
}
}
Es war eine Möglichkeit, mit gRPC zwischen Go und Dart zu kommunizieren. In einigen Unternehmen implementieren wir die Kommunikation mit der Server-Streaming-Methode. Daher möchte ich diese Informationen zu einem späteren Zeitpunkt weitergeben.
Recommended Posts