本文栗子,服务端实现对字符串的md5加密。客户端传递字符串通过rpc方式调用服务端,获得 md5 加密后的密文。 共通过三种方式实现,(1)go 语言 原生 RPC方式 (2) go语言原生 RPC + protobuff 实现 (3) GRPC 框架实现
#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)
}
需要先安装 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
#message.proto
syntax = "proto3";
package message;
option go_package = "./;message";
// 加密请求
message EncryptionRequest{
string str = 1;
}
// 加密返回值
message EncryptionResult{
string result = 1;
}
protoc ./message.proto --go_out=./
# 得到的目录结构
.
├── client_test.go
├── message
│ ├── message.pb.go
│ └── message.proto
└── server.go
#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())
}
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);
}
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
#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)
}
}