Go语言的rpc框架有两个比较有特色的设计:
- RPC打包时可以通过插件实现自定义编码和解码;
- RPC建立在抽象的io.ReadWriteCloser接口之上,可以实现不同的通信协议;
服务端代码:
const HelloSericeName = "study.jsonrpc.HelloService"
type RpcService interface {
Hello(request string,reply *string) error
}
//注册服务
func RegistService(serviceName string,srv RpcService) error {
return rpc.RegisterName(serviceName,srv)
}
type HelloService struct{}
func (HelloService) Hello(request string, reply *string) error {
*reply = "recieved:" + request + "\n"
return nil
}
func Run() {
err := RegistService(HelloSericeName, new(HelloService))
if err !=nil {
log.Fatalln(err)
}
listen, err := net.Listen("tcp", "127.0.0.1:9090")
if err !=nil {
log.Fatalln(err)
}
for {
conn, err := listen.Accept()
if err !=nil {
log.Fatalln(err)
}
//使用json编解码器
go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))
//go rpc.ServeConn(conn)
}
}
其他代码不变,只是最后改用json编解码器
相应的客户端代码:
type Client struct {
*rpc.Client
}
func (client *Client) Hello(request string, reply *string) error {
return client.Call(HelloSericeName+".Hello",request,reply)
}
func DialRpc(network string,addr string) (*Client,error) {
conn, err := net.Dial(network, addr)
if err !=nil {
return nil,err
}
//使用json编解码
client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
return &Client{client},nil
}
func Request() {
service, err := DialRpc("tcp", "127.0.0.1:9090")
if err !=nil {
log.Fatalln(err)
}
var reply string
err = service.Hello("Hello World !", &reply)
if err !=nil {
log.Fatalln(err)
}
fmt.Println(reply)
}
网友评论