golang rpc介绍
rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问。服务端注册一个对象,使它作为一个服务被暴露,服务的名字是该对象的类型名。注册之后,对象的导出方法就可以被远程访问。服务端可以注册多个不同类型的对象(服务),但注册具有相同类型的多个对象是错误的。
服务端代码样例:
package rpc import ( "net" "net/rpc" "net/rpc/jsonrpc" "time" "AgentManage/config" "github.com/astaxie/beego/logs" ) func Start() { addr := config.AppConfig.RpcAddr server := rpc.NewServer() server.Register(new(Hbs)) l, e := net.Listen("tcp", addr) if e != nil { logs.Error("rpc listen error:", e) } else { logs.Info("rpc listening", addr) } defer l.Close() for { conn, err := l.Accept() if err != nil { logs.Error("rpc listener accept fail:", err) time.Sleep(time.Duration(100) * time.Millisecond) continue } go server.ServeCodec(jsonrpc.NewServerCodec(conn)) } }
package rpc import ( "github.com/astaxie/beego/logs" "AgentManage/models" "fmt" "time" ) type HbsRequest struct { Hostname string `json:"hostname"` Version string `json:"version"` BuildTime string `json:"build_time"` } type HbsReply struct { Status int `json:"status"` Message string `json:"message"` Data interface{} `json:"data"` } type Hbs struct{} func (t *Hbs) HealthCheck(req HbsRequest, reply *HbsReply) error { err := models.HeartbeatCreateOrUpdate(req.Hostname, req.Version, req.BuildTime) if err != nil { logs.Error("rpc error:", req.Hostname, err) *reply = HbsReply{ Status: -1, Message: fmt.Sprint(err), } } *reply = HbsReply{ Message: "success", } return nil }
客户端代码
package main import ( "log" "net/rpc/jsonrpc" "fmt" "time" "net" ) type HbsRequest struct { Hostname string `json:"hostname"` Version string `json:"version"` BuildTime string `json:"build_time"` } type HbsReply struct { Status int `json:"status"` Message string `json:"message"` Data interface{} `json:"data"` } func main() { // Synchronous call for { //client, err := jsonrpc.Dial("tcp", "192.168.1.93:36870") client, err := net.DialTimeout("tcp", "192.168.1.93:36870", 3 * time.Second) if err != nil { log.Fatal("net.DialTimeout error:", err) } clientRpc := jsonrpc.NewClient(client) args := &HbsRequest{"shhnwangjian1", "1.2", "2018-05-25 09:12:44"} reply := HbsReply{} err = clientRpc.Call("Hbs.HealthCheck", args, &reply) if err != nil { log.Fatal("clientRpc.Call error:", err) } fmt.Println(reply) client.Close() time.Sleep(10 * time.Second) } }