go rpc
先看目录
以下代码按文件顺序展示
package main
import (
"fmt"
"jsongorpc/client_proxy"
)
func main(){
// 建立连接
client := client_proxy.NewInitConnection("tcp", "localhost:1234") //这里还是用的go语言rpc建立连接
var reply *string = new(string)
// 调用自己服务器注册的服务(可以理解成微服务)
erro := client.Hello("book", reply)
if erro != nil{
panic("调用失败")
}
// 打印结果
fmt.Println(*reply)
}
package client_proxy
import(
"net/rpc"
"jsongorpc/handler"
)
// 如果不这样做,我们封装一个普通函数里面,我们就要给这个函数传入call的实例。
// 为了不传这个call的实例,我们写一个结构体,继承call方法的实例,并用我们写的这个结构体封装调用call过程的func,
// 这样我们这个结构体实例,就即可以调用封装func又能调用call方法。
// 然后在另一个初始化函数里面,我们把call实例作为参数给我们写的结构体,完成继承。
// 其实这个封装过程别不简单,步骤也不少,最大的作用就是在我们以后调用的时候,更简单,封装本身并不简单。
// 封装的意义就在于让程序员以后调用的时候只关心业务逻辑代码
type HelloServiceStup struct{
*rpc.Client
}
func NewInitConnection(protocal string, address string) HelloServiceStup {
conn, err := rpc.Dial(protocal,address)
if err != nil{
panic("连接错误")
}
return HelloServiceStup{conn}
}
func (c *HelloServiceStup) Hello(request string, reply *string)error{
err := c.Call(handler.HelloServerName+".Hello", request, reply)
if err != nil{
panic("调用错误")
}
return nil
}
package handler
const HelloServerName = "handler/HelloService"
type HelloServer struct{}
func (hello *HelloServer) Hello(request string, reply *string)error{
*reply = "hi " + request
return nil
}
package main
import (
"net"
"net/rpc"
"jsongorpc/server_proxy"
"jsongorpc/handler"
)
func main(){
// 创建socket实例
listener, _ := net.Listen("tcp",":1234")
//把业务逻辑注册到rpc
//fmt.Println(handler.HelloServerName)
//_ = rpc.RegisterName(handler.HelloServerName, &handler.HelloServer{})
server_proxy.NewRegisterName{}.RegisterName(&handler.HelloServer{})
//socket接受请求任务
conn,_ := listener.Accept()
//rpc处理任务
rpc.ServeConn(conn)
}
package server_proxy
import (
"net/rpc"
"jsongorpc/handler"
)
type NewRegisterName struct {
//*rpc.Server
}
type HelloServerFace interface{
Hello(request string, reply *string)error
}
func (n NewRegisterName) RegisterName(helloserver HelloServerFace)error{
_ = rpc.RegisterName(handler.HelloServerName, helloserver)
return nil
}
封装思想总结:
以上封装主要有两点:
1:利用继承完成一个对象多函数调用,在client_proxy里有体现
2:利用多态(基于接口),完成一个函数参数可以接收不同的结构体对象
封装的意义
其实封装本身别不是简化代码,以前我不是这样理解的,我觉得封装就是简化代码。
其实封装目的是让程序员只关注业务逻辑本身,把业务逻辑之外的东西封装起来,方便以后复用。