Go - RPC

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)
}

你可能感兴趣的:(gorpc)