被调用的服务方法必须满足以下条件
- 方法的类型是暴露的
- 方法是暴露的
- 方法有两个参数,并且都是暴露的参数
- 第二个参数是指针类型
- 方法的返回类型必须是error
以商品订单为例,传入商品id,返回商品的详细信息。
syntax = "proto3";
package message;
message OrderRequest{
string orderId = 1;
}
message OrderInfo{
string OrderId = 1;
string OrderName = 2;
string OrderStatus = 3;
}
使用protobuf生成相应的go语言代码:
protoc ./message/message.proto --go_out=./
服务端代码:
type OrderService struct{
}
func (os *OrderService) GetOrderInfo(request message.OrderRequest,response *message.OrderInfo) error{
orderMap := map[string]message.OrderInfo{
"201626010302":{OrderId: "201626010302",OrderName: "耐克",OrderStatus: "待付款"},
"201626010303":{OrderId: "201626010303",OrderName: "贵人鸟",OrderStatus: "已付款"},
"201626010304":{OrderId: "201626010304",OrderName: "安踏",OrderStatus: "已发货"},
}
result := orderMap[request.OrderId]
if result.OrderId != ""{
*response = orderMap[request.OrderId]
}else{
return errors.New("not exist")
}
return nil
}
func main() {
orderService := new(OrderService)
// 注册相应的方法,也可以使用RegisterName方法进行注册,不过需要提供名称
rpc.Register(orderService)
/* HandleHTTP向DefaultRPCPath上的DefaultServer注册一个
用于RPC消息的HTTP处理程序,
并在DefaultDebugPath上注册一个调试处理程序。
仍然需要调用http.Serve()
*/
rpc.HandleHTTP()
// 监听端口
listen,err := net.Listen("tcp","localhost:8081")
if err != nil{
panic(err.Error())
}
http.Serve(listen,nil)
}
客户端代码:
func main() {
// DialHTTP连接到指定网络地址的HTTP RPC服务器,监听默认的HTTP RPC路径。
client,err := rpc.DialHTTP("tcp","localhost:8081")
if err != nil{
panic(err.Error())
}
request := message.OrderRequest{OrderId: "201626010301"}
var response *message.OrderInfo
// 通过Call方法调用RPC方法
err = client.Call("OrderService.GetOrderInfo",request,&response)
if err != nil{
panic(err.Error())
}
// 打印获取到的结果
fmt.Print(*response)
}
参考资料:
go语言官网
protobuf官网