筚路蓝缕,以启山林。抚有蛮夷,以属华夏。不鸣则已,一鸣惊人。 rpc:远程过程调用,是一个思想,一个概念。核心是分布式应用间通信,屏蔽不同语言,解耦(个人认为)。 net/rpc包是一个go自带的rpc实现方式,可以基于tcp、http、json rpc等方式进行调用。 gRpc基于Netty HTTP/2协议栈封装底层通信,启动时启动一个Netty server。 特别提醒(踩坑后可以返回来再看):如果没有用go module模式,那么需要在src下手动创建google.golang.org目录并进入该目录手动执行git clone https://e.coding.net/robinqiwei/googleprotobuf.git protobuf,否则包不能正确拉取(报找不到google.golang.org/protobuf/proto…等一堆错);如果用的go module模式,那么这个是自动完成的,无需手动创建。 目录 实践目标:server端与client端可以实现通信。此实例采用TCP方式调用。项目目录结构: pub.go 服务端 客户端 分别启动服务端和客户端,控制台分别如下: http、json-rpc等方式的调用可移步:https://blog.csdn.net/ffzhihua/article/details/83270771 实践目标:服务端有两个服务,客户端我要使用(调用)这两个服务。 背景设计:远端某个地方有两个服务:分别是加密服务和解密服务,client调用时只需传明文或密文作为参数即可。 项目结构如下: 通过.proto文件约定好服务接口、参数等,通过工具protoc-gen-go生成客户端和服务端共用的对照表。 secret.proto 生成的secret.pb.go挺长,这里就不贴了。生成方式及环境搭建可移步https://blog.csdn.net/HYZX_9987/article/details/106462026 服务端 客户端 分别启动服务端、客户端,控制台分别如下:
——《左传`宣公十二年》
net/rpc
package base1_public import ( "fmt" "net/rpc" ) const HelloServiceName = "pkg.HelloService" type HelloServiceInterface interface { HelloS(request string, reply *string) error // 之所以命名为HelloS,是为了验证与其对应之处 } func RegisterHelloService(svc HelloServiceInterface) error { return rpc.RegisterName(HelloServiceName, svc) } type HelloService struct{} func (p *HelloService) HelloS(request string, reply *string) error { *reply = "hello:" + request fmt.Println("服务端回复:", *reply) return nil }
package main import ( "log" "net" "net/rpc" "rpc-test/base1_public" ) func main() { base1_public.RegisterHelloService(new(base1_public.HelloService)) listener, err := net.Listen("tcp", ":3234") if err != nil { log.Fatal("ListenTCP error:", err) } for { conn, err := listener.Accept() if err != nil { log.Fatal("Accept error:", err) } go rpc.ServeConn(conn) // 此次server被终止时才会执行下次循环继续开启新的server,否则一直阻塞等待 } }
package main import ( "fmt" "log" "net/rpc" "rpc-test/base1_public" ) type HelloServiceClient struct { *rpc.Client } func DialHelloService(network, address string) (*HelloServiceClient, error) { c, err := rpc.Dial(network, address) if err != nil { return nil, err } return &HelloServiceClient{Client: c}, nil } func (p *HelloServiceClient) start(request string, reply *string) error { // 方式1 //return p.Client.Call(base1_public.HelloServiceName+".HelloS", request, reply) // HelloS与接口的方法名对应即可 // 方式2 helloCall := p.Client.Go(base1_public.HelloServiceName+".HelloS", request, reply, nil) //helloCall = <-helloCall.Done return (<-helloCall.Done).Error //if err := helloCall.Error; err != nil { // log.Fatal(err) //} } func main() { client, err := DialHelloService("tcp", "localhost:3234") if err != nil { log.Fatal("dialing:", err) } var reply string err = client.start("哈哈哈", &reply) if err != nil { log.Fatal(err) } fmt.Println("收到的回复:", reply) }
服务端回复: hello:哈哈哈 收到的回复: hello:哈哈哈
google.golang.org/grpc
syntax = "proto3"; package proto; service SecretService { rpc Encrypt(SecretRequest) returns (SecretResponse) {} rpc Decrypt(SecretRequest) returns (SecretResponse) {} } message SecretRequest { string request = 1; } message SecretResponse { string response = 1; }
package main import ( "context" "encoding/base64" "fmt" pt "gRpc-demo/proto" "google.golang.org/grpc" "log" "net" ) const PORT = "9001" type SecretServiceStruct struct{} // 加密服务 func (s *SecretServiceStruct) Encrypt(ctx context.Context, r *pt.SecretRequest) (*pt.SecretResponse, error) { log.Print("调用了加密服务:", r.Request) secret := base64.StdEncoding.EncodeToString([]byte(r.Request)) return &pt.SecretResponse{Response: r.GetRequest() + "加密成功:" + secret}, nil } // 解密服务 func (s *SecretServiceStruct) Decrypt(ctx context.Context, r *pt.SecretRequest) (*pt.SecretResponse, error) { log.Print("调用了解密服务:", r.Request) str, err := base64.StdEncoding.DecodeString(r.Request) if err != nil { log.Fatalf("服务端解密失败: %v", err.Error()) return &pt.SecretResponse{Response: ""}, err } return &pt.SecretResponse{Response: r.GetRequest() + "解密成功:" + string(str)}, nil } func main() { server := grpc.NewServer() pt.RegisterSecretServiceServer(server, &SecretServiceStruct{}) lis, err := net.Listen("tcp", ":"+PORT) if err != nil { log.Fatalf("net.Listen err: %v", err) } addr := fmt.Sprintf("%s", lis.Addr()) log.Printf("Listening on %v", addr) log.Fatal(server.Serve(lis)) }
package main import ( "context" pt "gRpc-demo/proto" "google.golang.org/grpc" "log" "strings" ) const PORT = "9001" var str = `this is gRpc` func main() { // 上面gRPC的服务没有提供证书支持,因此客户端在连接服务器中通过grpc.WithInsecure()选项跳过对服务器证书的验证 conn, err := grpc.Dial(":"+PORT, grpc.WithInsecure()) if err != nil { log.Fatalf("grpc.Dial err: %v", err) } defer conn.Close() client := pt.NewSecretServiceClient(conn) resp0, err := client.Encrypt(context.Background(), &pt.SecretRequest{ Request: str, }) if err != nil { log.Fatalf("client.Encrypt err: %v", err) } secretStr := strings.Split(resp0.GetResponse(), ":")[1] log.Printf("请求加密服务: %s", secretStr) resp1, err := client.Decrypt(context.Background(), &pt.SecretRequest{ Request: secretStr, }) if err != nil { log.Fatalf("client.Decrypt err: %v", err) } resStr := strings.Split(resp1.GetResponse(), ":")[1] log.Printf("请求解密服务: %s", resStr) }
服务端: 2020/06/01 09:41:20 Listening on [::]:9001 2020/06/01 09:41:37 调用了加密服务:this is gRpc 2020/06/01 09:41:37 调用了解密服务:dGhpcyBpcyBnUnBj 客户端: 2020/06/01 09:41:37 请求加密服务: dGhpcyBpcyBnUnBj 2020/06/01 09:41:37 请求解密服务: this is gRpc
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算