• Go中的RPC支持与处理


    在Go中net/rpc标准包提供了编写RPC服务需要的系列函数。net/rpc包允许RPC客户端通过网络或者IO连接调用一个远端对象的public方法。在RPC服务端,可将一个对象注册为可访问的服务,之后该对象的公开方法就能够被远程调用。一个RPC服务端可以注册多个不同类型的对象,但是不允许注册同一类型的多个对象。

    一个对象中的方法只有满足如下条件,才能被RPC服务端设置为可远程调用:

    • 必须是在对象外部可访问的(首字母大写)
    • 必须有两个参数,且参数类型都必须是包外部可以访问的类型或者Go内置类型
    • 第二个参数必须是一个指针
    • 方法必须返回一个error类型的值

    用代码表示如下:

    func (t* T) MethodName(argType T1, argType *T2) (error)

    在这行代码中,类型T, T1, T2默认会使用Go内置的encoding/gob包进行编码解码。该方法的第一个参数表示有RPC客户端传入的参数,第二个参数表示要返回给RPC客户端的结果,最后返回一个error类型的结果。

    RPC服务端可以通过调用rpc.ServeConn处理单个连接请求,但是大多数情况下,都是通过TCP或HTTP在某个网络地址上监听来创建服务。在客户端,net/rpc包提供了rpc.Dial()和rpc.DialHTTP()方法来与指定的RPC服务器建立连接。在建立连接之后,Go的net.rpc包允许我们使用同步(rpc.Call)或者异步(rpc.Go)方式接收RPC服务端的处理结果。

    Server端代码:

     1 package server
     2 
     3 import (
     4     "errors"
     5     "log"
     6     "net"
     7     "net/http"
     8     "net/rpc"
     9 )
    10 
    11 type Args struct {
    12     A, B int
    13 }
    14 
    15 type Quotiten struct {
    16     Quo, Rem int
    17 }
    18 
    19 type Arith int
    20 
    21 func (t *Arith) Multiply(args *Args, reply *int) error {
    22     *reply = args.A * args.B
    23     return nil
    24 }
    25 
    26 func (t *Arith) Divide(args *Args, quo *Quotiten) error {
    27     if args.B == 0 {
    28         return errors.New("divide by zero")
    29     }
    30     quo.Quo = args.A / args.B
    31     quo.Rem = args.A % args.B
    32     return nil
    33 }
    34 
    35 func init() {
    36     arith := new(Arith)
    37     rpc.Register(arith)
    38     rpc.HandleHTTP()
    39     l, e := net.Listen("tcp", ":1234")
    40     if e != nil {
    41         log.Fatal("listen error: ", e)
    42     }
    43     go http.Serve(l, nil)
    44 }

    客户端调用代码

     1 package main
     2 
     3 import (
     4     "./server"
     5     "fmt"
     6     "log"
     7     "net/rpc"
     8 )
     9 
    10 func main() {
    11     client, err := rpc.DialHTTP("tcp", "localhost:1234")
    12     if nil != err {
    13         log.Fatal("dialing:", err)
    14     }
    15 
    16     args := &server.Args{7, 8}
    17     var reply int
    18     err = client.Call("Arith.Multiply", args, &reply)
    19     if nil != err {
    20         log.Fatal("arith error:", err)
    21     }
    22     fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
    23 }

  • 相关阅读:
    学习笔记
    聊聊字节序
    SPDK发送和接收连接请求的处理
    企业设备维护——不仅仅是解决问题
    怎样快速找到某一行代码的git提交记录
    生产环境中利用软链接避免"rm -rf /"的方法
    程序员五年小结
    Django Model 数据库增删改查
    python中字符串列表字典常用方法
    python编辑配置
  • 原文地址:https://www.cnblogs.com/lniwn/p/3377847.html
Copyright © 2020-2023  润新知