GO言語の三つのRPCの使い方

31453 ワード

本文の栗は、サーバーで文字列のmd 5暗号化を実現します.クライアント転送文字列はrpcでサービス端末を呼び出し、md 5暗号化された暗号文を取得する.全部で三つの方法で実現して、(1)go言語のオリジナルRPC方式(2)go言語のオリジナルRPC+protobuffを実現します.(3)GRPCフレームワークを実現します.
1.go原生rpc
#server.go
package main

import (
	"crypto/md5"
	"encoding/hex"
	"net"
	"net/http"
	"net/rpc"
)
//      
type EncryptionUtil struct {
     
}

//     
func (eu *EncryptionUtil) Encryption(req string, resp *string) error {
     
	*resp = ToMd5(req)
	return nil
}
//    md5   
func ToMd5(s string) string{
     
	m := md5.New()
	m.Write([]byte (s))
	return hex.EncodeToString(m.Sum(nil))
}

func main() {
     
	//       
	encryption :=  new(EncryptionUtil)
	err := rpc.Register(encryption)  //rpc.RegisterName("      ",encryption)
	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 := "mclink"
	var resp *string
	//     
	err = client.Call("EncryptionUtil.Encryption", req, &resp)
	if err!= nil {
     
		panic(err.Error())
	}
	fmt.Println(*resp)

	//     
	syncCall := client.Go("EncryptionUtil.Encryption", req, &resp, nil)
	//   ,           
	replayDone := syncCall.Done
	fmt.Println(replayDone)
	fmt.Println(*resp)

}

2.rpcはprotobufと結合する.
2.1 mac設置grpc環境
grpcコマンドと対応する関連パッケージを先にインストールする必要があります.
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.2プロファイルの作成
#message.proto
syntax = "proto3";

package message;
option go_package = "./;message";

//     
message  EncryptionRequest{
     
  string str = 1;
}
//      
message EncryptionResult{
     
  string result = 1;
}

2.3 protoファイルをコンパイルする
protoc ./message.proto --go_out=./ 


#        
.
├── client_test.go
├── message
│   ├── message.pb.go
│   └── message.proto
└── server.go

2.4プログラミング
#server.go
//     
type EncryptionService struct {
     
}

//     ,          ,            pb       
func (es *EncryptionService) Encryption(request *message.EncryptionRequest, response *message.EncryptionResult) error{
     
	md5Str := ToMd5(request.GetStr())
	response.Result = md5Str
	return nil
}

//       md5
func ToMd5(s string) string{
     
	m := md5.New()
	m.Write([]byte (s))
	return hex.EncodeToString(m.Sum(nil))
}


func main() {
     
	//       
	encryption :=  new(EncryptionService)
	err := rpc.Register(encryption)  //rpc.RegisterName("      ",encryption)
	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_test.go
func TestClient(t *testing.T)  {
     
	//     
	client, err := rpc.DialHTTP("tcp", "localhost:8081")
	if err != nil {
     
		panic(err.Error())
	}

	req := message.EncryptionRequest{
     Str: "mclink"}
	resp := message.EncryptionResult{
     }
	//     
	err = client.Call("EncryptionService.Encryption", &req, &resp)
	if err!= nil {
     
		panic(err.Error())
	}
	fmt.Println(resp.GetResult())

}
3.GRPC実現
3.1プロファイルを作成する
syntax = "proto3";

package message;
option go_package = "./;message";

//     
message  EncryptionRequest{
     
  string str = 1;
}
//      
message EncryptionResult{
     
  string result = 1;
}

//   service  ,     
service EncryptionService {
     
  rpc Encryption(EncryptionRequest) returns (EncryptionResult);
}
2.3 protoファイルをコンパイルする
go get -u google.golang.org/grpc

protoc ./message.proto --go_out=plugins=grpc:./ 


#        
.
├── client_test.go
├── message
│   ├── message.pb.go
│   └── message.proto
└── server.go

2.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)
	}
}