Go 的RPC 相关的基础信息
1. 环境配置(MacOS)
1.1 protoc 安装
# 1. brew 安装
brew search protobuf
brew install protobuf # 可以指定版本protobuf@21
# 验证是否安装成功
protoc --version
# 2. 源码安装
https://github.com/protocolbuffers/protobuf/releases #下载对应的版本,放入GOPATH中的bin目录下
1.2 protoc-gen-go 安装
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# 安装过程中会出现无法下载,需要自行“走强”
# 验证
protoc-gen-go help
# protoc-gen-go: unknown argument "help" (this program should be run by protoc, not directly)
# ps:我觉得只要识别到,就应该安装成功了
1.3 protoc-gen-go-grpc 安装
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# 同 protoc-gen-go
# 验证
protoc-gen-go-grpc -version
# protoc-gen-go-grpc 1.3.0
2. Proto转成桩代码
2.1 proto 生成
参考地址:https://protobuf.dev/
syntax = "proto3";
import public "google/protobuf/timestamp.proto";
option go_package = "./news";
option java_multiple_files = true;
option java_package = "wiki.micah.news";
option java_outer_classname = "News";
package news;
message News {
int64 id = 1;
string title = 2;
string keyword = 3;
string desc = 4;
google.protobuf.Timestamp happen_time = 5;
int32 state = 6;
google.protobuf.Timestamp create_time = 7;
google.protobuf.Timestamp update_time = 8;
}
message NewsRequest {
string name = 1;
}
message NewsResponse {
repeated News news_list = 1;
}
service SearchService {
rpc Search (NewsRequest) returns (NewsResponse);
}
2.2 git 仓库打分支
# 打tag
git tag -a v0.1.0-alpha -m "预发布"
# 推送tag到目标上
git push origin v0.1.0-alpha
3. 程序编写
3.1 go.mod编写
require (
github.com/supermicah/Protobufs v0.1.2-alpha
google.golang.org/grpc v1.58.1
)
3.2 client 编写
根据grpc的helloworld进行编写
package main
import (
"context"
"flag"
"log"
"time"
pb "github.com/supermicah/Protobufs/news/micah/wiki/news"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
const (
defaultName = "world"
)
var (
addr = flag.String("addr", "localhost:50051", "the address to connect to")
)
func main() {
flag.Parse()
// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer func() { _ = conn.Close() }()
c := pb.NewSearchServiceClient(conn)
// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.Search(ctx, &pb.NewsRequest{Name: "你好"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("NewsList: %s", r)
}
3.3 server编写
package main
import (
"context"
"flag"
"fmt"
"google.golang.org/protobuf/types/known/timestamppb"
"log"
"net"
pb "github.com/supermicah/Protobufs/news/micah/wiki/news"
"google.golang.org/grpc"
)
var (
port = flag.Int("port", 50051, "The server port")
)
// server is used to implement helloworld.GreeterServer.
type server struct {
pb.UnimplementedSearchServiceServer
}
// Search implements helloworld.GreeterServer
func (s *server) Search(ctx context.Context, in *pb.NewsRequest) (*pb.NewsResponse, error) {
log.Printf("Received: %v", in.GetName())
newsList := make([]*pb.News, 0)
newsList = append(newsList, &pb.News{
Id: 1,
Title: "test",
Keyword: "test",
Desc: "test",
HappenTime: ×tamppb.Timestamp{Seconds: 1, Nanos: 1},
State: 0,
CreateTime: ×tamppb.Timestamp{Seconds: 2, Nanos: 2},
UpdateTime: ×tamppb.Timestamp{Seconds: 3, Nanos: 3},
})
return &pb.NewsResponse{NewsList: newsList}, 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.RegisterSearchServiceServer(s, &server{})
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
3.4 整体项目结构
