なんで?ていうとgRPCもGoもgoogleが開発したものだから相性がいいはず。ってのと、WindowsでC++でgRPCするってなると、マイクロソフトコンパイラが必要になってCommunity EditionとBuild toolsをインストールするってなって、で、何度も触れているようにLicense Termsが気に食わないのでやだっ。WindowsでMSYS+mingwとかWSL+mingwでもgRPCができるのかもしれないとは思っている(実は途中までやって挫折している)けど、先にGoでやった方が理解が深まるかもしれないと思っている。
参考サイトは総本山(https://grpc.io/)。
では、総本家のGoをクリックしてQuick startを単にその説明をたどっていく(<--まぁちゃんとできるようになったゾっていう記録だけ)。
Prerequisites
Goを入れんかいって書いてあるけど、これは入っている。
Protocol buffer compilerを入れんかいって書いてある。"Protocol Buffer Compiler Installation"をつついて、
apt install -y protobuf-compiler
protoc --version
ってやれって書いてあるので、そのままやってみる。Warningにバージョンが大事だ的な記述があるけど、まずは入れてみろってことやな。
3以上じゃないといかんよって書いてあるのでOKってことで。
で、Quick startに戻って、Go pluginsってのを入れろって書いてあるので言われた通りにやってみる。
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
(なんかカレントディレクトリに入れちまわないだろうかとls撃ってるのは気にしない)
で、PATHを設定しろって書いてある。
export PATH="$PATH:$(go env GOPATH)/bin"
これが"go env GOPATH"ってなんや?ってなるけど、$HOMEのgo/binらしい。なので、
export PATH="$PATH:$HOME/go/bin"
Get the example code
gitからダウンロードしてexampleフォルダに移動しろって書いてある。git cloneすると、カレントディレクトリにぶっこんでくれるので、そこはうまいことやらんといかん。
git clone -b v1.70.0 --depth 1 https://github.com/grpc/grpc-go
cd grpc-go/examples/helloworld
Run the example
単に実行しろって書いてある。
go run greeter_server/main.go
で別のターミナルで
go run greeter_client/main.go
そすっと、 こんな感じであっさり動いちゃう。ほかの言語のQuick startはまぁまぁしんどいのにやっぱGoびいきだねきっと。
Update the gRPC service
英語なのでもう読むのがしんどくなってきたが、helloworld/helloworld.protoを編集してprotocしろってことらしい。
helloworld/helloworld.proto
- // Copyright 2015 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.
-
- syntax = "proto3";
-
- option go_package = "google.golang.org/grpc/examples/helloworld/helloworld";
- option java_multiple_files = true;
- option java_package = "io.grpc.examples.helloworld";
- option java_outer_classname = "HelloWorldProto";
-
- package helloworld;
-
- // 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;
- }
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld/helloworld.proto
エラー吐いてないからいいんやろ、きっと。総本山によると、これで、helloworld/helloworld.pb.goとhelloworld/helloworld_grpc.pb.goができるらしい。心配ならタイムスタンプを確認する。
Update and run the application
greeter_server/main.go
- /*
- *
- * Copyright 2015 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.
- *
- */
-
- // Package main implements a server for Greeter service.
- package main
-
- import (
- "context"
- "flag"
- "fmt"
- "log"
- "net"
- "google.golang.org/grpc"
- pb "google.golang.org/grpc/examples/helloworld/helloworld"
- )
-
- var (
- port = flag.Int("port", 50051, "The server port")
- )
- // server is used to implement helloworld.GreeterServer.
- type server struct {
- pb.UnimplementedGreeterServer
- }
-
- // SayHello implements helloworld.GreeterServer
- func (s *server) SayHello(_ context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
- log.Printf("Received: %v", in.GetName())
- return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
- }
- func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
- return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil
- }
- func main() {
- flag.Parse()
- lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
- if err != nil {
- log.Fatalf("failed to listen: %v", err)
- }
- s := grpc.NewServer()
- pb.RegisterGreeterServer(s, &server{})
- log.Printf("server listening at %v", lis.Addr())
- if err := s.Serve(lis); err != nil {
- log.Fatalf("failed to serve: %v", err)
- }
- }
greeter_client/main.go
- /*
- *
- * Copyright 2015 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.
- *
- */
-
- // Package main implements a client for Greeter service.
- package main
-
- import (
- "context"
- "flag"
- "log"
- "time"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials/insecure"
- pb "google.golang.org/grpc/examples/helloworld/helloworld"
- )
-
- const (
- defaultName = "world"
- )
-
- var (
- addr = flag.String("addr", "localhost:50051", "the address to connect to")
- name = flag.String("name", defaultName, "Name to greet")
- )
-
- func main() {
- flag.Parse()
- // Set up a connection to the server.
- conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
- if err != nil {
- log.Fatalf("did not connect: %v", err)
- }
- defer conn.Close()
- c := pb.NewGreeterClient(conn)
- // Contact the server and print out its response.
- ctx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
- if err != nil {
- log.Fatalf("could not greet: %v", err)
- }
- log.Printf("Greeting: %s", r.GetMessage())
- r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: *name})
- if err != nil {
- log.Fatalf("could not greet: %v", err)
- }
- log.Printf("Greeting: %s", r.GetMessage())
- }
んでもって、実行してみる。
go run greeter_server/main.go
で別のターミナルで
go run greeter_client/main.go --name=Alice
そすっと、
まぁこんな感じでうまくいく(そりゃあたりまえよ)。
Windows実行ファイルとしてコンパイルしてみる。
cd greeter_server
GOOS=windows GOARCH=amd64 go build -o greeter_server.exe main.go
ls -la
cd ../greeter_client
GOOS=windows GOARCH=amd64 go build -o greeter_client.exe main.go
ls -la
cd ..
いちおうできた風。
アクセス許可のダイアログが出るので許可してっと。とりあえず動いている風。
これがWindowsで動くかどうか。
\\WSL$からWSL内をほじっていって、実行ファイルをコピーしてDocuments下あたりにコピペする。で、ファイルのプロパティで実行許可を与えた。
実行ファイルがあるフォルダのアドレスバーにcmdって入れるとコマンドプロンプト画面が出る。2つ出す。で、実行。
うごいたー。
やっぱりgRPCやるのにGoは適している!<--そりゃそうだろ
WSLでGOOSとGOARCHで指定するだけでWindows実行ファイルができちゃうってのが大変すばらしいよ。
0 件のコメント:
コメントを投稿