go rpc实例------1. 基于tcp/gob. 2. 基于http/gob. 3. tcp/jsonrpc

版权声明:本文为博主原创文章,转载时请务必注明本文地址, 禁止用于任何商业用途, 否则会用法律维权。 https://blog.csdn.net/stpeace/article/details/82924646

      前面玩过grpc, 要安装grpc库,要安装protobuf库等,好多库啊 。通信协议是tcp, 采用protobuf序列化。

      下面来看看go原生的rpc(不需要安装一些杂七杂八的库): 1. 基于tcp/gob. 2. 基于http/gob. 3. tcp/jsonrpc.  其中,1和2采用了gob序列化, 有局限性,而 3采用的是json序列化,比较通用。

       

      1.  基于tcp/gob

       server.go:

package main

import (
    "net"
    "log"
    "net/rpc"
)

type Params struct {
    Width, Height int;
}

type Rect struct{}

// 1. 方法名Area必须大写
// 2. 必须有两个参数,且参数必须是外部能访问的类型或内置类型,且第二个参数必须是指针类型
// 3. 返回值必须是error类型
func (r *Rect) Area(p Params, ret *int) error {
    *ret = p.Width * p.Height
    return nil
}

 
func main() {
    rect := new(Rect)
    rpc.Register(rect)  // 注册

    tcplisten, err := net.Listen("tcp", "0.0.0.0:8888")
    if err != nil {
        log.Fatal(err)
    }

    for {
        conn, err := tcplisten.Accept()
        if err != nil {
            continue
        }

        go rpc.ServeConn(conn)
    }
}

         跑起来。       

        client.go:

package main
 
import (
    "net/rpc"
    "fmt"
    "log"
    "time"
)
 
type Params struct {
    Width  int
    Height int
}
 
func main() {
    rpc, err := rpc.Dial("tcp", "127.0.0.1:8888")
    if err != nil {
        log.Fatal(err)
    }

    for {
        ret := 0
        err = rpc.Call("Rect.Area", Params{50, 100}, &ret)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(ret)

        time.Sleep(time.Second)
    }
}

         跑起来。客户端结果为:

5000
5000
5000
5000
5000
       如果用tcpdump抓包, 则看不出gob的内容是什么意思。

  

       2. 基于http/gob:

       server.go:

package main

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

type Params struct {
    Width, Height int;
}

type Rect struct{}

// 1. 方法名Area必须大写
// 2. 必须有两个参数,且参数必须是外部能访问的类型或内置类型,且第二个参数必须是指针类型
// 3. 返回值必须是error类型
func (r *Rect) Area(p Params, ret *int) error {
    *ret = p.Width * p.Height
    return nil
}

 
func main() {
    rect := new(Rect)
    rpc.Register(rect)  // 注册


    rpc.HandleHTTP();
    err := http.ListenAndServe(":8080", nil);
    if err != nil {
        log.Fatal(err);
    }
}

         跑起来。

         client.go:

package main
 
import (
    "net/rpc"
    "fmt"
    "log"
    "time"
)
 
type Params struct {
    Width  int
    Height int
}
 
func main() {
    rpc, err := rpc.DialHTTP("tcp", "127.0.0.1:8080");
    if err != nil {
        log.Fatal(err);
    }

    for {
        ret := 0
        err = rpc.Call("Rect.Area", Params{50, 100}, &ret)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(ret)

        time.Sleep(time.Second)
    }
}

        客户端也跑起来,结果:

5000
5000
5000
5000
5000
5000
5000
5000
5000

       如果用tcpdump抓包, 则看不出gob的内容是什么意思。

       3.  tcp/jsonrpc

       server.go:

package main

import (
    "net"
    "log"
    "net/rpc"
    "net/rpc/jsonrpc"
)

type Params struct {
    Width, Height int;
}

type Rect struct{}

// 1. 方法名Area必须大写
// 2. 必须有两个参数,且参数必须是外部能访问的类型或内置类型,且第二个参数必须是指针类型
// 3. 返回值必须是error类型
func (r *Rect) Area(p Params, ret *int) error {
    *ret = p.Width * p.Height
    return nil
}

 
func main() {
    rect := new(Rect)
    rpc.Register(rect)  // 注册

    tcplisten, err := net.Listen("tcp", "0.0.0.0:8888")
    if err != nil {
        log.Fatal(err)
    }

    for {
        conn, err := tcplisten.Accept()
        if err != nil {
            continue
        }

        go jsonrpc.ServeConn(conn)
    }
}

         跑起来。

         client.go:

package main
 
import (
    "net/rpc/jsonrpc"
    "fmt"
    "log"
    "time"
)
 
type Params struct {
    Width  int
    Height int
}
 
func main() {
    rpc, err := jsonrpc.Dial("tcp", "127.0.0.1:8888");
    if err != nil {
        log.Fatal(err);
    }

    for {
        ret := 0
        err = rpc.Call("Rect.Area", Params{50, 100}, &ret)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(ret)

        time.Sleep(time.Second)
    }
}

        跑起来,客户端结果为:

5000
5000
5000
5000
5000
5000
5000

       用tcpdump抓包看看:

11:21:57.620895 IP 127.0.0.1.58698 > 127.0.0.1.8888: Flags [P.], seq 207:276, ack 115, win 12135, options [nop,nop,TS val 534958593 ecr 534957588], length 69
        0x0000:  0200 0000 4500 0079 0000 4000 4006 0000  ....E..y..@.@...
        0x0010:  7f00 0001 7f00 0001 e54a 22b8 54cc e11f  .........J".T...
        0x0020:  573c c601 8018 2f67 fe6d 0000 0101 080a  W<..../g.m......
        0x0030:  1fe2 d201 1fe2 ce14 7b22 6d65 7468 6f64  ........{"method
        0x0040:  223a 2252 6563 742e 4172 6561 222c 2270  ":"Rect.Area","p
        0x0050:  6172 616d 7322 3a5b 7b22 5769 6474 6822  arams":[{"Width"
        0x0060:  3a35 302c 2248 6569 6768 7422 3a31 3030  :50,"Height":100
        0x0070:  7d5d 2c22 6964 223a 3532 387d 0a         }],"id":528}.
11:21:57.620928 IP 127.0.0.1.8888 > 127.0.0.1.58698: Flags [.], ack 276, win 11622, options [nop,nop,TS val 534958593 ecr 534958593], length 0
        0x0000:  0200 0000 4500 0034 0000 4000 4006 0000  ....E..4..@.@...
        0x0010:  7f00 0001 7f00 0001 22b8 e54a 573c c601  ........"..JW<..
        0x0020:  54cc e164 8010 2d66 fe28 0000 0101 080a  T..d..-f.(......
        0x0030:  1fe2 d201 1fe2 d201                      ........
11:21:57.620935 IP 127.0.0.1.8888 > 127.0.0.1.58698: Flags [.], ack 276, win 11622, options [nop,nop,TS val 534958593 ecr 534958593], length 0
        0x0000:  0200 0000 4500 0034 0000 4000 4006 0000  ....E..4..@.@...
        0x0010:  7f00 0001 7f00 0001 22b8 e54a 573c c601  ........"..JW<..
        0x0020:  54cc e164 8010 2d66 fe28 0000 0101 080a  T..d..-f.(......
        0x0030:  1fe2 d201 1fe2 d201                      ........
11:21:57.621160 IP 127.0.0.1.8888 > 127.0.0.1.58698: Flags [P.], seq 115:153, ack 276, win 11622, options [nop,nop,TS val 534958593 ecr 534958593], length 38
        0x0000:  0200 0000 4500 005a 0000 4000 4006 0000  ....E..Z..@.@...
        0x0010:  7f00 0001 7f00 0001 22b8 e54a 573c c601  ........"..JW<..
        0x0020:  54cc e164 8018 2d66 fe4e 0000 0101 080a  T..d..-f.N......
        0x0030:  1fe2 d201 1fe2 d201 7b22 6964 223a 3532  ........{"id":52
        0x0040:  382c 2272 6573 756c 7422 3a35 3030 302c  8,"result":5000,
        0x0050:  2265 7272 6f72 223a 6e75 6c6c 7d0a       "error":null}.

         果然, 使用的是json编码, 有点意思。

         就这样, 不多说。

                    

猜你喜欢

转载自blog.csdn.net/stpeace/article/details/82924646