go rpc几个示例
这个属于标准库的内容,这里列举几个有趣的例子
客户端异步调用
func main() {
client, err := rpc.DialHTTP("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
args1 := &Args{7, 8}
var reply int
multiplyReply := client.Go("Arith.Multiply", args1, &reply, nil)
args2 := &Args{15, 6}
var quo Quotient
divideReply := client.Go("Arith.Divide", args2, &quo, nil)
ticker := time.NewTicker(time.Millisecond)
defer ticker.Stop()
var multiplyReplied, divideReplied bool
for !multiplyReplied || !divideReplied {
select {
case replyCall := <-multiplyReply.Done:
if err := replyCall.Error; err != nil {
fmt.Println("Multiply error:", err)
} else {
fmt.Printf("Multiply: %d*%d=%d\n", args1.A, args1.B, reply)
}
multiplyReplied = true
case replyCall := <-divideReply.Done:
if err := replyCall.Error; err != nil {
fmt.Println("Divide error:", err)
} else {
fmt.Printf("Divide: %d/%d=%d...%d\n", args2.A, args2.B, quo.Quo, quo.Rem)
}
divideReplied = true
case <-ticker.C:
fmt.Println("tick")
}
}
}
定制方法名
server
func main() {
arith := new(Arith)
rpc.RegisterName("math", arith)
rpc.HandleHTTP()
if err := http.ListenAndServe(":1234", nil); err != nil {
log.Fatal("serve error:", err)
}
}
client
func main() {
client, err := rpc.DialHTTP("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
args := &Args{7, 8}
var reply int
err = client.Call("math.Multiply", args, &reply)
if err != nil {
log.Fatal("Multiply error:", err)
}
fmt.Printf("Multiply: %d*%d=%d\n", args.A, args.B, reply)
}
TCP协议
rpc默认是HTTP协议,我们也可以指定TCP
server
func main() {
l, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("listen error:", err)
}
arith := new(Arith)
rpc.Register(arith)
rpc.Accept(l)
}
可以看内容实现
func (server *Server) Accept(lis net.Listener) {
for {
conn, err := lis.Accept()
if err != nil {
log.Print("rpc.Serve: accept:", err.Error())
return
}
go server.ServeConn(conn)
}
}
client
func main() {
client, err := rpc.Dial("tcp", ":1234")
if err != nil {
log.Fatal("dialing:", err)
}
args := &Args{7, 8}
var reply int
err = client.Call("Arith.Multiply", args, &reply)
if err != nil {
log.Fatal("Multiply error:", err)
}
fmt.Printf("Multiply: %d*%d=%d\n", args.A, args.B, reply)
}
自定义编码
这部分其实就是你自己重新仿照下面这种实现一下就ok,无难度倒是不少复制粘贴的活
type gobServerCodec struct {
rwc io.ReadWriteCloser
dec *gob.Decoder
enc *gob.Encoder
encBuf *bufio.Writer
closed bool
}
https://juejin.im/post/5eb6d492e51d454ddf2359b3#heading-6
自定义服务器
src/net/rpc/server.go
var DefaultServer = NewServer()
func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }
func RegisterName(name string, rcvr interface{}) error {
return DefaultServer.RegisterName(name, rcvr)
}
func ServeConn(conn io.ReadWriteCloser) {
DefaultServer.ServeConn(conn)
}
func ServeCodec(codec ServerCodec) {
DefaultServer.ServeCodec(codec)
}
DefaultServer是全局共享的,所以不能使用DefaultServer,直接使用
func NewServer() *Server {
return &Server{}
}
一个没有高级趣味的人。
email:hushui502@gmail.com