33

golang实现RPC调用

 4 years ago
source link: https://studygolang.com/articles/26736
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

RPC远程调用

Z3eyeu3.png!web

RPC通信过程

  1. 调用者(客户端Client)以本地调用的方式发起调用
  2. Client stub(客户端存根)收到调用后,负责将被调用的方法名、参数等打包编码成特定格式的能进行网络传输的消息体;
  3. Client stub将消息体通过网络发送给服务端;
  4. Server stub(服务端存根)收到通过网络接收到消息后按照相应格式进行拆包解码,获取方法名和参数;
  5. Server stub根据方法名和参数进行本地调用;
  6. 被调用者(Server)本地调用执行后将结果返回给server stub;
  7. Server stub将返回值打包编码成消息
  8. 通过网络发送给客户端
  9. Client stub收到消息后,进行拆包解码,返回给Client;
  10. Client得到本次RPC调用的最终结果.

RPC实现

  1. server端代码
package main

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

type MathUtil struct {
}

func (mu *MathUtil) CirculateArea(req float32, resp *float32) error {
    *resp = math.Pi * req * req
    return nil
}
func main() {
    mathUtil := new(MathUtil)
    /*将服务对象进行注册*/
    err := rpc.Register(mathUtil)
    if err != nil {
        panic(err.Error())
    }
    /*将函数的服务注册到HTTP上*/
    rpc.HandleHTTP()

    /*在特定的端口进行监听*/
    listen, err := net.Listen("tcp", ":8081")
    if err != nil {
        panic(err.Error())
    }
    http.Serve(listen, nil)
}
  1. client端代码
package main

import (
    "fmt"
    "net/rpc"
)

func main() {
    client,err:=rpc.DialHTTP("tcp","localhost:8081")
    if err != nil {
        panic(err.Error())

    }
    var req float32=3 
    /*同步调用方式*/
    /*
    var resp *float32
    err=client.Call("MathUtil.CirculateArea",req,&resp)
    if err != nil {
        panic(err.Error())
    }
    fmt.Println(*resp)*/
    
    /*异步通道*/
    var respSync *float32
    syncCall:=client.Go("MathUtil.CirculateArea",req,&respSync,nil)
    replayDone:=<-syncCall.Done
    fmt.Println(replayDone)
    fmt.Println(*respSync)
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK