Go语言扩展 1.RPC

go net的rpc

Go语言的rpc包的是建立在net包基础之上的(内置)。基于TCP协议

  • 服务端

    #server.go
    package main
    
    import (
        "net"
        "net/http"
        "net/rpc"
    )
    
    // 计算
    type Sum struct {
    }
    
    // 计算方法
    func (s *Sum) sums(req string, resp *string) error {
        *resp = req+1
        return nil
    }
    
    func main() {
        // 功能对象注册
        sum :=  new(Sum)
        err := rpc.Register(sum)  
    
        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)
    }
    
  • 客户端

    #client.go
    package main
    
    import (
        "fmt"
        "net/rpc"
    )
    
    func main()  {
        // 建立连接
        client, err := rpc.DialHTTP("tcp", "localhost:8081")
        if err != nil {
            panic(err.Error())
        }
        // 参数
        req := 100
        var resp *string
    
        // 同步调用
        err = client.Call("Sum.sums", req, &resp)
        if err!= nil {
            panic(err.Error())
        }
        fmt.Println(*resp)
    
        // 异步调用
        syncCall := client.Go("Sum.sums", req, &resp, nil)
        // 阻塞,异步调用成功后解除阻塞
        replayDone := <-syncCall.Done
        fmt.Println(replayDone)
        fmt.Println(*resp)
    }
    

基于Json实现 rpc

Go语言的rpc包的是建立在net包基础之上的(内置)。基于TCP协议,再原有的rpc结构上把传入传出方式改为json字符串就可以实现jsonrpc

grpc 实现 rpc

rpc 结合 protobuf 实现grpc

  • 1.首先要安装grpc(基于mac)

    brew tap grpc/grpc
    brew install protobuf
    go get -u github.com/golang/protobuf/proto
    go get -u github.com/golang/protobuf/protoc-gen-go
    
  • 2.编写 proto 条件

    #message.proto
    syntax = "proto3";
    
    package message;
    option go_package = "./;message";
    
    // 加密请求
    message  EncryptionRequest{
    string str = 1;
    }
    // 加密返回值
    message EncryptionResult{
    string result = 1;
    }
    
  • 3.编译proto
    protoc ./message.proto --go_out=./

  • 4.编写程序

    • 服务端
      ```
      #server.go
      // 加密服务实现类
      type EncryptionServiceImpl struct {
      }

      // 加密程序
      func (es *EncryptionServiceImpl) Encryption(ctx context.Context, request *message.EncryptionRequest) (*message.EncryptionResult, error){

        md5Str := ToMd5(request.GetStr())
        res := message.EncryptionResult{Result:md5Str}
        return &res,nil
      

      }

      // 简单封装的 md5
      func ToMd5(s string) string{

        m := md5.New()
        m.Write([]byte (s))
        return hex.EncodeToString(m.Sum(nil))
      

      }

    func main() {
        // 创建一个 grpc server
        server := grpc.NewServer()

        message.RegisterEncryptionServiceServer(server, new(EncryptionServiceImpl))

        lis, err := net.Listen("tcp", ":8081")
        if err != nil {
            panic(err.Error())
        }
        _ = server.Serve(lis)
    }
    ```
* 客户端
    ```
    #client_test.go
    func TestClient(t *testing.T)  {
        //1、Dail连接
        conn, err := grpc.Dial("localhost:8081", grpc.WithInsecure())
        if err != nil {
            panic(err.Error())
        }
        defer conn.Close()
        encryptionServiceClient := message.NewEncryptionServiceClient(conn)

        orderRequest := &message.EncryptionRequest{Str: "mclink"}
        result, err := encryptionServiceClient.Encryption(context.Background(), orderRequest)
        if result != nil {
            fmt.Println(result.Result)
        }
    }
    ```

rpcx 实现 rpc

KiteX 实现 rpc

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。