准备
1,安装grpc
go get -u google.golang.org/grpc
2, 安装go语言protobuf生成器protoc-gen-go
go get -u google.golang.org/protobuf/cmd/protoc-gen-go
3, 通过下面连接,找到合适版本并安装protoc工具,如windows选择 protoc-3.19.5-win64.zip
https://github.com/protocolbuffers/protobuf/releases/tag/v3.19.5
注意: 将GOPATH下的bin目录以及protoc的bin目录配置在环境变量中否则会找不到相关命令
编写proto文件
# server/proto/test.proto 文件
syntax = "proto3";
package test;
option go_package = "../proto";
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
生成protobuf
cd server/proto
protoc --proto_path=. --go_out=plugins=grpc:. *
编写服务端程序
# server/main.go
package main
import (
"context"
"google.golang.org/grpc"
"log"
"net"
pb "server/proto"
)
type server struct {
}
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
return &pb.HelloResponse{
Message: "hello " + in.Name,
}, nil
}
func main() {
listen, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal("net.Listen err", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
if err = s.Serve(listen); err != nil {
log.Fatal("s.Serve err", err)
}
}
编写客户端
# 先将server/proto 目录复制到 client/proto
# client/main.go
package main
import (
pb "client/proto"
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
"net"
"net/http"
)
type server struct {
httpServer http.Server
}
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/sayHello" {
_ = r.ParseForm()
message := sayHello(r.Form.Get("name"))
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "text/html")
w.Write([]byte("<h1>" + message + "</h1>"))
}
}
func sayHello(name string) string {
conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatal("连接失败:", err)
}
defer conn.Close()
client := pb.NewGreeterClient(conn)
resp, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
log.Fatal("调用失败:", err)
}
return resp.GetMessage()
}
func main() {
listen, err := net.Listen("tcp", ":80")
if err != nil {
log.Fatal("net.Listen err", err)
}
s := &server{}
s.httpServer.Handler = s
if err = s.httpServer.Serve(listen); err != nil {
log.Fatal("httpServer.Serve err", err)
}
}
验证
通过postman请求 http://127.0.0.1/sayHello 接口, 参数 name 为jack, 看到响应了 <h1>hello jack</h1>