RPC
RPC(Remote Procedure Call: 近程过程调用)是一个计算机通信协议,该协定容许运行于一台计算机的程序调用另一个地址空间(通常为一个凋谢网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额定地为这个交互作用编程(无需关注细节)。
gRPC(https://grpc.io/about)
gRPC是一个古代的开源高性能近程过程调用(RPC)框架,能够在任何环境中运行。它能够高效地连贯数据中心中和跨数据中心的服务,并反对可插入的负载平衡、跟踪、健康检查和身份验证。它还实用于分布式计算,以连贯设施、挪动应用程序和浏览器到后端服务。
- 编写.proto文件,创立user.proto文件
syntax = "proto3";option go_package = "./pb_protobuf/white_board;white_board";import "google/api/annotations.proto";package white_board;message ImCreateBoardRequest { int64 id = 1; int32 page_count = 2; string room_no = 3; string doc_id = 4; string url_background = 5; string page_pos = 6; string file_url = 7; string uuid = 8; string nickname = 9;}message ImBoardInfoResponse{ int64 id = 1; int32 page_count = 2; string doc_id = 3; string create_time = 4; string update_time = 5;}message ImGetBoardListByRoomNoResponse{ repeated ImBoardInfoResponse BoardList = 1;}message ImGetBoardByIdRequest{ int64 id = 1;}message ImGetBoardByRoomNoRequest{ string room_no = 1;}message ImBoardResponse{}service Board{ rpc CreateBoard(ImCreateBoardRequest) returns (ImBoardInfoResponse){} rpc DeleteBoardById(ImGetBoardByIdRequest) returns (ImBoardResponse){} rpc DeleteBoardByRoomNo(ImGetBoardByRoomNoRequest) returns (ImBoardResponse){} rpc GetBoardListByRoomNo(ImGetBoardByRoomNoRequest) returns(ImGetBoardListByRoomNoResponse){}}
syntax = "proto3";
其中第一行指定了咱们应用 protocol buffers的版本,这里应用proto3.
option go_package = "path;name";
path:指定生成buffers文件的寄存目录,name:给package定义别名,能够与package不统一。
我的项目目录构造
.├── README.md├── app│ ├── api│ │ ├── board.go│ ├── dao│ │ ├── board.go│ ├── model│ │ ├── board.go│ └── service│ ├── board.go├── config│ ├── config.go│ ├── config.local.yml│ ├── config.yml│ ├── database│ │ └── database.go│ └── init.go├── constant│ └── constant.go├── gateway│ └── gateway.go├── go.mod├── go.sum├── interfaces│ ├── impls│ │ ├── api_error.go│ │ └── rpc.go│ └── inter.go├── log│ └── debug.log├── main.go├── middleware│ ├── auth.go│ ├── grpc_exception.go│ ├── recovery.go│ └── zap_log.go├── pb_protobuf│ ├── white_board│ │ ├── board.pb.go├── protobuf│ ├── white_board│ │ ├── board.proto├── s.sh└── util ├── grpc.go └── util.go
编写shell脚本s.sh
# !bin/shproto_files=`find ./protobuf -maxdepth 2 -name "*.proto"`for proto_file in ${proto_files[*]}do echo `protoc --proto_path=../ -I/$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.14.6/third_party/googleapis -I./protobuf --go_out=plugins=grpc:. ${proto_file}`done
执行shell脚本文件./s.sh,在pb_protobuf文件下主动生成white_board文件夹,以及对应的board.pb.go文件。
测试
创立grpc服务端,新建serve.go文件
package mainimport ( "google.golang.org/grpc" "im-whiteboard/app/api" "im-whiteboard/pb_protobuf/white_board" "log" "net")func main() { // 创立 Tcp 连贯 listener, err := net.Listen("tcp", ":8028") if err != nil { log.Fatalf("监听失败: %v", err) } // 创立gRPC服务 grpcServer := grpc.NewServer() // Tester 注册服务实现者 // 此函数在 board.pb.go 中,主动生成 white_board.RegisterBoardServer(grpcServer,&api.Board{}) err = grpcServer.Serve(listener) if err != nil { log.Fatalf("failed to serve: %v", err) }}
创立grpc 客户端client.go文件
package mainimport ( "context" im_service "im-whiteboard/pb_protobuf/white_board" "log" "google.golang.org/grpc")// 定义申请地址const ( //ADDRESS string = constant.WhiteBoardMedia ADDRESS string = "127.0.0.1:8028")// main 办法实现对 gRPC 接口的申请func main() { conn, err := grpc.Dial(ADDRESS, grpc.WithInsecure()) if err != nil { log.Fatalln("Can't connect: " + ADDRESS) } defer conn.Close() client := im_service.NewBoardClient(conn) res, err := client.GetBoardListByRoomNo(context.Background(),&im_service.ImGetBoardByRoomNoRequest{ RoomNo: "c0c6487ab418dabab0ccc9f32c36531b", }) if err != nil { log.Fatalln("Do Format error:" + err.Error()) }else{ log.Println("res",res) }}
而后别离启动 server 和 client端,我的项目波及mysql,redis,mongodb这里不开展阐明。
功败垂成,此时客户端与服务端以及实现全副通信。