使用grpc
https://github.com/binfer-go/example-grpc
Proto
//命令 protoc --go_out=plugins=grpc:. .\router.proto
syntax = "proto3";
package proto;
service RouteGuide{
rpc Getfeature(Point) returns (Feature) {} // 普通
rpc ListFeatures(Point) returns (stream Feature) {} // 服务流
rpc RecordRoute(stream Point) returns (Feature) {} // 客户端流
rpc RouteChat(stream Point) returns (stream Feature){} // 双向流
}
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
message Feature{
int32 id = 1;
bytes data = 2;
}
- 简单RPC
// 服务端
var port = ":9900"
type routeGuideServer struct {
//pb proto.UnimplementedRouteGuideServer
}
func (router *routeGuideServer) Getfeature(ctx context.Context, point *proto.Point) (*proto.Feature, error) {
fmt.Println("------ getfeature:", point.Longitude, point.Latitude)
return &proto.Feature{Message:"getfeature"}, nil
}
func main() {
server, err := net.Listen("tcp", "127.0.0.1" + port)
if err != nil {
log.Fatalf("tcp listen error: %s \n", err)
}
grpcServer := grpc.NewServer()
proto.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
_ = grpcServer.Serve(server)
}
// 客户端
const (
address = "localhost:9900"
)
func main() {
ctx, _ := context.WithTimeout(context.TODO(), time.Second)
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure())
if err != nil {
log.Fatalf("client server error: %s \n", err)
}
defer conn.Close()
routeServe := proto.NewRouteGuideClient(conn)
feature, err := routeServe.Getfeature(context.Background())
if err != nil {
log.Printf("client feature error: %s \n", err)
}
fmt.Println(feature)
}
- 服务器流式 RPC
// 服务端
func (router *routeGuideServer) ListFeatures(point *proto.Point, server proto.RouteGuide_ListFeaturesServer) error {
fmt.Println("------ listfeature:", point.Latitude, point.Longitude, server.Context())
_ = server.Send(&proto.Feature{Message: "listfeature"})
_ = server.RecvMsg(nil)
return nil
}
func main() {
server, err := net.Listen("tcp", "127.0.0.1" + port)
if err != nil {
log.Fatalf("tcp listen error: %s \n", err)
}
grpcServer := grpc.NewServer()
proto.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
_ = grpcServer.Serve(server)
}
// 客户端
const (
address = "localhost:9900"
)
func main() {
ctx, _ := context.WithTimeout(context.TODO(), time.Second)
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure())
if err != nil {
log.Fatalf("client server error: %s \n", err)
}
defer conn.Close()
routeServe := proto.NewRouteGuideClient(conn)
feature, err := routeServe.RecordRoute(context.Background())
if err != nil {
log.Printf("client feature error: %s \n", err)
}
_ = feature.Send(&proto.Point{
Latitude: 111,
Longitude: 222,
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
fmt.Println(feature.Recv())
}
- 客户端流式 RPC
// 服务端
func (router *routeGuideServer) RecordRoute(stream proto.RouteGuide_RecordRouteServer) error {
fmt.Println("------ recordRoute:")
point, err := stream.Recv()
if err == io.EOF {
_ = stream.SendAndClose(&proto.Feature{
Id: 1,
Data: []byte("hello"),
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
}
fmt.Println("=======", point)
return nil
}
func main() {
server, err := net.Listen("tcp", "127.0.0.1" + port)
if err != nil {
log.Fatalf("tcp listen error: %s \n", err)
}
grpcServer := grpc.NewServer()
proto.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
_ = grpcServer.Serve(server)
}
// 客户端
func main() {
ctx, _ := context.WithTimeout(context.TODO(), time.Second)
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure())
if err != nil {
log.Fatalf("client server error: %s \n", err)
}
defer conn.Close()
routeServe := proto.NewRouteGuideClient(conn)
feature, err := routeServe.RecordRoute(context.Background())
if err != nil {
log.Printf("client feature error: %s \n", err)
}
_ = feature.Send(&proto.Point{
Latitude: 111,
Longitude: 222,
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
fmt.Println(feature)
}
- 双向流式 RPC
// 服务端
func (router *routeGuideServer) RouteChat(stream proto.RouteGuide_RouteChatServer) error {
fmt.Println("------ routeChat:")
point, err := stream.Recv()
if err != nil {
return err
}
if err == io.EOF {
_ = stream.Send(&proto.Feature{
Id: 1,
Data: []byte("hello"),
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
}
fmt.Println("=====", point)
_ = stream.Send(&proto.Feature{
Id: 1,
Data: []byte("hello"),
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
return nil
}
func main() {
server, err := net.Listen("tcp", "127.0.0.1" + port)
if err != nil {
log.Fatalf("tcp listen error: %s \n", err)
}
grpcServer := grpc.NewServer()
proto.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})
_ = grpcServer.Serve(server)
}
// 客户端
func main() {
ctx, _ := context.WithTimeout(context.TODO(), time.Second)
conn, err := grpc.DialContext(ctx, address, grpc.WithInsecure())
if err != nil {
log.Fatalf("client server error: %s \n", err)
}
defer conn.Close()
routeServe := proto.NewRouteGuideClient(conn)
feature, err := routeServe.RouteChat(context.Background())
if err != nil {
log.Printf("client feature error: %s \n", err)
}
_ = feature.Send(&proto.Point{
Latitude: 111,
Longitude: 222,
XXX_NoUnkeyedLiteral: struct{}{},
XXX_unrecognized: nil,
XXX_sizecache: 0,
})
fmt.Println(feature.Recv())
}