編寫基於gRPC的C/S通訊模型
阿新 • • 發佈:2019-02-02
1、編寫.proto檔案
包含:1)定義service,用service{}包起來
service ServiceName{
rpc funcname1(Request) returns (Reponse){}
rpc funcname2(Request) returns (Reponse){}
}
2)message Request{}
3)message Response{}
2、編譯生成golang對應的rpc程式碼
命令:protoc --go_out=plugins=grpc:{go程式碼的輸出路徑,生成的.pb.go檔案所在目錄} xxx.proto在生成的.pb.go檔案中,包含如下內容://有關請求、應答的struct type Request struct{} //請求struct type Response struct{} //應答struct //service的客戶端的API,客戶端會呼叫funcname1和funcname2 type ServiceNameClient interface{ funcname1(三個引數) funcname2(三個引數) } type serviceNameClient struct{} func NewServiceNameClient() ServiceNameClient{} //建立客戶端 func (c *serviceNameClient) funcname1(三個引數)(*Response, error) func (c *serviceNameClient) funcname2(三個引數)(*Response, error) //service的伺服器的API,伺服器會呼叫funcname1和funcname2 type ServiceNameServer interface{ funcname1(兩個引數) funcname2(兩個引數) } 注意:伺服器並沒有對應的struct,也沒有實現兩個函式,所以需要在伺服器的main.go中建立server struct,並實現該介面的這兩個函式,即server的method //使用pb包呼叫註冊已實現的rpc介面類server func RegisterServiceNameServer(){ s.RegisterService() }
3、編寫客戶端
//定義目的埠??、伺服器地址 const( address = "127.0.0.1:50051" defaultname = "strings" ) //主函式 func main(){ //發起連線 conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil{} //錯誤處理 defer conn.Close() //防止記憶體洩漏 //建立客戶端 c := 包名.NewServiceNameClient(conn) //包名就是剛剛編譯生成的.pb.go中的package,因為呼叫的函式就是.pb.go中的,所以package是.pb.go中的package name := defaultName if len(os.Args) > 1 { name = os.Args[1] } //發起請求 r, err := c.funcname1()//發起請求,返回響應 log.Printf("%s", r.Message)//列印響應的內容 }
4、編寫伺服器端
const ( port = ":50051"//宣告監聽埠 ) //主函式 func main(){ lis, err := net.Listen("tcp", port) //監聽指定埠,使用tcp協議 if err != nil{} type server struct{} //server用來實現包名.ServiceNameServer,這是個介面,介面中的函式就是funcname1和funcname2,和Client對應的struct的內建函式是一樣的,只不過client的程式碼通過直接編譯就生成了,但是server的內建函式,需要在main函式中實現。所以在main函式中需要定義server struct,然後實現兩個附屬於server struct的內建函式,即實現ServerNameServer介面。 //需要實現.pb.go中的ServerNameServer介面 func (s *server) funcname1(兩個引數){} func (s *servre) funcname2(兩個引數){} //生成一個rpc伺服器 s := grpc.NewServer() //註冊已實現的rpc介面類server 包名.RegisterServiceNameServer(s, &server{}) //在grpc伺服器上註冊反射service reflection.Register(s) if err := s.Serve(lis); err != nil { log.Fatalf("%v", err) } }