前情回顾
继上篇《【轻知识】(糙译)Go使用proto3、官方示例代码》,我根据官方demo生成了一个文件addressbook.data
。
正好grpc的实现,也别浪费了这个demo。还记得那个proto文件么?addressbook.proto
。实现rpc呢?我需要简单的更改下文件。增加Service
贴代码
温馨提示:
记得 go get -u google.golang.org/grpc
protoc addressbook.proto --go_out=plugins=grpc:./ 如果不加grpc就没有rpc代码实现
不加grpc跟加了的对比
proto 文件如下
syntax = "proto3";
package tutorial;
import "google/protobuf/timestamp.proto";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
string number = 1;
PhoneType type =2;
}
repeated PhoneNumber phones = 4;
google.protobuf.Timestamp last_updated = 5;
}
message AddressBook {
repeated Person people = 1;
}
message AddressListRequest {
int32 page = 1;
}
message AddressListResponse {
AddressBook book_list = 1;
}
service AddressListService {
rpc AddressList (AddressListRequest) returns (AddressListResponse);
}
接着看服务器端代码:
读取addressbook.data(正好没浪费)
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net"
pb "rpc/tutorial"
"github.com/golang/protobuf/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)
type server struct{}
func (s *server) AddressList(ctx context.Context, in *pb.AddressListRequest) (*pb.AddressListResponse, error) {
fileData, err := ioutil.ReadFile("./addressbook.data")
if err != nil {
log.Fatalln("Error reading file:", err)
}
book := &pb.AddressBook{}
if err := proto.Unmarshal(fileData, book); err != nil {
log.Fatalln("Failed to parse address book:", err)
}
fmt.Printf("%v\n", book)
return &pb.AddressListResponse{BookList: book}, nil
}
func main() {
s := grpc.NewServer()
pb.RegisterAddressListServiceServer(s, &server{})
reflection.Register(s)
lis, err := net.Listen("tcp", ":9555")
if err != nil {
log.Println(err)
}
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %s", err)
}
}
client端代码
package main
import (
"context"
"encoding/json"
"fmt"
"log"
pb "rpc/tutorial"
"time"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial("127.0.0.1:9555", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewAddressListServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.AddressList(ctx, &pb.AddressListRequest{Page: 1})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
json, err := json.Marshal(r.BookList)
if err != nil {
panic(err)
}
fmt.Printf("%v", string(json))
}
执行client端代码输出
{
"people":[
{
"name":"mike",
"id":123,
"email":"mike@gmail.com",
"phones":[
{
"number":"178933"
}
]
},
{
"name":"mike",
"id":123434,
"email":"mike@gmail.com",
"phones":[
{
"number":"178933",
"type":1
},
{
"number":"98783",
"type":2
},
{
"number":"123333"
}
]
}
]
}
参考资料:
- 《grpc/grpc-go》https://github.com/grpc/grpc-go/tree/master/examples
- 《grpc Tutorials》 https://grpc.io/docs/tutorials/
有疑问加站长微信联系(非本文作者)