1.rpc
1.1.服务端
package main
import (
"net"
"net/rpc"
)
type HelloService struct {}
func (s *HelloService) Hello(request string,reply *string) error {
*reply = "hello" + request
return 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 main
import (
"fmt"
"log"
"net/rpc"
)
func main() {
client, err := rpc.Dial("tcp", "localhost:8848")
if err != nil {
log.Fatalln("dialing:",err)
}
var reply string
err = 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 main
import (
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
type HelloService struct {}
func (s *HelloService) Hello(request string,reply *string) error {
*reply = "hello" + request
return 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 main
import (
"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 string
err = client.Call("HelloService.Hello", "world", &reply)
if err != nil {
panic("调用错误")
}
fmt.Println(reply)
}
3.基于http的rpc
package main
import (
"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.Writer
io.ReadCloser
}{
ReadCloser:r.Body,
Writer:w,
}
rpc.ServeRequest(jsonrpc.NewServerCodec(conn))
})
http.ListenAndServe(":1234",nil)
}