关于go:Go-RPC

11次阅读

共计 2019 个字符,预计需要花费 6 分钟才能阅读完成。

Go – RPC

参考

https://geektutu.com/post/quick-go-rpc.html

RPC 简介

RPC(Remote Procedure Call) 近程过程调用,计算机通信协议的一种
RPC 下 调用程序 会搁置 client 节点的机器,被调办法子程序 会搁置 Server 节点的机器, client 通过向 Server 发送申请、Server 回调响应来获取 调用程序 的 后果
调用方和执行方别离在不同的机器上 

本地调用的例子

$ mkdir ./goRpc && cd goRpc && go mod init goRpc
$ vi main.go
package main

import("fmt")

type Result struct {
    Num int
    Ret int
}

type Cal int

func (cal *Cal) Square(num int) *Result{
    return &Result{
        Num: num,
        Ret: num*num,
    }
}

func main(){c := new(Cal)
    ret := c.Square(8)
    fmt.Println(ret)
    fmt.Println(ret.Num)
    fmt.Println(ret.Ret)
}
$ go run main.go                                                                           
&{8 64}
8
64$ 

RPC 被调用子办法须要满足的条件

func (t *T) MethodName(argType T1, replyType *T2) error
 办法类型(T)是导出的(首字母大写)办法名(MethodName)是导出的
办法有 2 个参数 (argType T1, replyType *T2),均为导出 / 内置类型
办法的第 2 个参数一个指针 (replyType *T2)
办法的返回值类型是 error
// 革新 Square 函数
...
func (cal *Cal) Square(num int, ret *Result) error{
    ret.Num = num
    ret.Ret = num * num
    return nil
}
...

RPC 服务与调用

创立服务端

$ mkdir goRPC_server && cd goRPC_server && go mod init goRPC_server
$ vi server.go

package main

import(
    "fmt"
    "net/rpc"
    "net/http"
)

type Result struct {
    Num int
    Ret int
}

type Cal int


func (cal *Cal) Square(num int, ret *Result) error{
    ret.Num = num
    ret.Ret = num * num
    return nil
}


func main(){rpc.Register(new(Cal))
    rpc.HandleHTTP()

    fmt.Println("server running on port 8080...")
    if err := http.ListenAndServe(":8080", nil);err != err{fmt.Println("error:", err)
    }
}
$ go run server.go
server running on port 8080...

创立客户端 (同步调用)

$ mkdir goRPC_client && cd goRPC_client && go mod init goRPC_client
$ vi client.go
package main

import(
    "fmt"
    "net/rpc"
)

type Result struct {
    Num int
    Ret int
}

func main(){
    var ret Result

    client, err := rpc.DialHTTP("tcp", ":8080")
    if err != nil{fmt.Println("create rpc client error:", err)
        return
    }

    if err := client.Call("Cal.Square", 8, &ret);err != nil{fmt.Println("failed to call Cal.Square:", err)
        return
    }

    fmt.Printf("success to call Cal.Square of 8: %d\n", ret.Ret)
}
$ go run client.go                     
success to call Cal.Square of 8: 64

创立客户端 (异步调用)

package main

import(
    "fmt"
    "net/rpc"
)

type Result struct {
    Num int
    Ret int
}

func main(){
    var ret Result

    client, err := rpc.DialHTTP("tcp", ":8080")
    if err != nil{fmt.Println("create rpc client error:", err)
        return
    }

    asyCall := client.Go("Cal.Square", 8, &ret, nil)
    <-asyCall.Done // 阻塞以后程序直到 RPC 调用完结

    fmt.Printf("success to call Cal.Square of 8: %d\n", ret.Ret)
}
正文完
 0