zoukankan      html  css  js  c++  java
  • 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 }

  • 相关阅读:
    LeetCode刷题记录2020-10-07之动态规划入门!!!线性DP(二)
    LeetCode刷题记录2020-10-06之动态规划入门!!!线性DP
    LeetCode刷题记录2020-10-05之Double Pointer!!!
    Python核心编程之属性查找过程!
    Python核心编程之元类!
    Python配置文件的导入方式和源码分析!
    大数据架构入门之二:埋点数据流程
    day46 css第二part
    day44天 HTTP协议 和前端html协议
    day39 视图 触发器 事务 存储过程 函数 流程控制 索引与慢查询优化
  • 原文地址:https://www.cnblogs.com/lniwn/p/3377847.html
Copyright © 2011-2022 走看看