文件目录结构:
book@ubuntu:~/pt1416/02-hellogolang/grpcTest$ ls -l
total 48
-rw-rw-r-- 1 book book 159 3月 30 17:43 go.mod
drwxrwxr-x 3 book book 4096 3月 30 19:31 protodir
book@ubuntu:~/pt1416/02-hellogolang/grpcTest$ cat go.mod
module grpcTest
go 1.15
require (
golang.org/x/net v0.0.0-20220325170049-de3da57026de
google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.26.0
)
book@ubuntu:~/pt1416/02-hellogolang/grpcTest$ cd protodir
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ pwd
/home/book/pt1416/02-hellogolang/grpcTest/protodir
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ ll
total 36
drwxrwxr-x 3 book book 4096 3月 30 19:31 ./
drwxrwxr-x 8 book book 4096 3月 30 18:08 ../
drwxrwxr-x 3 book book 4096 3月 30 19:19 github.com/
-rw-rw-r-- 1 book book 630 3月 30 19:18 hello_world.proto
-rw-rw-r-- 1 book book 498 3月 30 19:31 server.go
-rw-rw-r-- 1 book book 498 3月 30 19:31 client.go
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ tree -f .
.
├── ./github.com
│ └── ./github.com/lixd
│ └── ./github.com/lixd/grpc-go-example
│ └── ./github.com/lixd/grpc-go-example/helloworld
│ ├── ./github.com/lixd/grpc-go-example/helloworld/hello.go
│ └── ./github.com/lixd/grpc-go-example/helloworld/hello_world.pb.go
├── ./hello_world.proto
└── ./server.go
└── ./client.go
4 directories, 8 files
其中 github.com为命令行生成;
1 hello_world.proto
//声明proto的版本 只有 proto3 才支持 gRPC
syntax = "proto3";
// 将编译后文件输出在 github.com/lixd/grpc-go-example/helloworld/helloworld 目录
option go_package = "github.com/lixd/grpc-go-example/helloworld";
// 指定当前proto文件属于helloworld包
package helloworld;
// 定义一个名叫 greeting 的服务
service Greeter {
// 该服务包含一个 SayHello 方法 HelloRequest、HelloReply分别为该方法的输入与输出
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 具体的参数定义
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
2 protoc 编译
方法1:(推荐)
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ protoc --go_out=plugins=grpc:. ./*.proto
方法2:
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ mkdir helloworld
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ protoc --proto_path=. --go_out=helloworld --go_opt=paths=source_relative hello_world.proto
注意:
方法1和方法2生成的区别是:grpc服务。
生成之后的代码,有些区别;
这里采用方法1;
生成目录和文件:
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld$ pwd
/home/book/pt1416/02-hellogolang/grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld$ ls -l
total 16
-rw-rw-r-- 1 book book 9757 3月 30 19:19 hello_world.pb.go
3 hello.go
位置(新生成的文件 hello_world.pb.go同级目录下):/home/book/pt1416/02-hellogolang/grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld$ ls -l
total 16
-rw-rw-r-- 1 book book 315 3月 30 19:19 hello.go
-rw-rw-r-- 1 book book 9757 3月 30 19:19 hello_world.pb.go
源码:
package helloworld
import (
"log"
"golang.org/x/net/context"
)
type HelloServer struct {
}
func (h *HelloServer) SayHello(ctx context.Context, msg *HelloRequest) (*HelloReply, error) {
log.Printf("received message body from client:%s", msg.Name)
return &HelloReply{Message: "Hello from the server!"}, nil
}
4 server.go
package main
import (
"log"
"net"
"grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld"
"google.golang.org/grpc"
)
func main() {
log.Println("server is running...")
lis, err := net.Listen("tcp", ":9000")
if err != nil {
log.Fatalf("failed to server on Port :%v", err)
}
s := helloworld.HelloServer{}
gServer := grpc.NewServer()
helloworld.RegisterGreeterServer(gServer, &s)
if err := gServer.Serve(lis); err != nil {
log.Fatalf("failed to grpc server:%v", err)
}
}
5 client.go
package main
import (
"context"
"log"
"grpcTest/protodir/github.com/lixd/grpc-go-example/helloworld"
"google.golang.org/grpc"
)
func main() {
var conn *grpc.ClientConn
conn, err := grpc.Dial(":9000", grpc.WithInsecure())
if err != nil {
log.Fatalf("could not connect:%s", err)
}
defer conn.Close()
c := helloworld.NewGreeterClient(conn)
msg := helloworld.HelloRequest{
Name: "Grpc: hello from client.",
}
rsp, err := c.SayHello(context.Background(), &msg)
if err != nil {
log.Fatalf("err where calling sayHello:%v", err)
}
log.Printf("respond from Server :%s", rsp.Message)
}
上述 grpcTest 为在grpcTest目录下执行的命令:
book@ubuntu:~/pt1416/02-hellogolang/grpcTest$ go mod init grpcTest
6 先执行server.go
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ go run server.go
2022/03/30 19:35:35 server is running...
2022/03/30 19:36:09 received message body from client:Grpc: hello from client.
7 再执行client.go
book@ubuntu:~/pt1416/02-hellogolang/grpcTest/protodir$ go run client.go
2022/03/30 19:36:09 respond from Server :Hello from the server!