1.rpc
1.1.服务端
package mainimport ("net""net/rpc")type HelloService struct {}func (s *HelloService) Hello(request string,reply *string) error {*reply = "hello" + requestreturn nil}func main() {_ := rpc.RegisterName("HelloService", &HelloService{})listener, err := net.Listen("tcp", ":8848")if err != nil {panic("监听端口失败")}conn, err := listener.Accept()if err != nil {panic("建立连接失败")}rpc.ServeConn(conn)}
其中Hello方法必须满足Go语言的RPC规则:方法只能有两个可序列化的参数,其中第二个参数是指针类型,并且返回一个error类型,同时必须是公开的方法。
然后就可以将HelloService类型的对象注册为一个RPC服务:(TCP RPC服务)。
其中rpc.Register函数调用会将对象类型中所有满足RPC规则的对象方法注册为RPC函数,所有注册的方法会放在HelloService服务空间之下。然后我们建立一个唯一的TCP链接,并且通过rpc.ServeConn函数在该TCP链接上为对方提供RPC服务。
1.2.客户端
package mainimport ("fmt""log""net/rpc")func main() {client, err := rpc.Dial("tcp", "localhost:8848")if err != nil {log.Fatalln("dialing:",err)}var reply stringerr = client.Call("HelloService.Hello", "world", &reply)if err != nil {log.Fatalln(err)}fmt.Println(reply)}
通过rpc.Dial拨号RPC服务,然后通过client.Call调用具体的RPC方法。在调用client.Call时,第一个参数是用点号链接的RPC服务名字和方法名字,第二和第三个参数分别我们定义RPC方法的两个参数。
2.rpc支持json
package mainimport ("net""net/rpc""net/rpc/jsonrpc")type HelloService struct {}func (s *HelloService) Hello(request string,reply *string) error {*reply = "hello" + requestreturn nil}func main() {rpc.RegisterName("HelloService",new(HelloService))listener, err := net.Listen("tcp", ":8090")if err != nil {panic("启动错误")}for {conn, err := listener.Accept()if err != nil {panic("接收")}go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))}}
用rpc.ServeCodec函数替代了rpc.ServeConn函数,传入的参数是针对服务端的json编解码器。
package mainimport ("fmt""net""net/rpc""net/rpc/jsonrpc")func main() {conn, err := net.Dial("tcp", ":1234")if err != nil {panic("连接错误")}client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))var reply stringerr = client.Call("HelloService.Hello", "world", &reply)if err != nil {panic("调用错误")}fmt.Println(reply)}
3.基于http的rpc
package mainimport ("io""net/http""net/rpc""net/rpc/jsonrpc")type HelloService struct {}func main() {rpc.RegisterName("HelloService",new(HelloService))http.HandleFunc("/jsonrpc", func(w http.ResponseWriter, r *http.Request) {var conn io.ReadWriteCloser = struct {io.Writerio.ReadCloser}{ReadCloser:r.Body,Writer:w,}rpc.ServeRequest(jsonrpc.NewServerCodec(conn))})http.ListenAndServe(":1234",nil)}
