您现在的位置是:主页 > news > 网站的流程/网站建设山东聚搜网络
网站的流程/网站建设山东聚搜网络
admin2025/5/5 19:55:07【news】
简介网站的流程,网站建设山东聚搜网络,广州白云区今天的消息,如何在海外进行推广文章目录gRPC四种通信模式RPC(Unary RPC)服务端流RPC客户端流RPC双向流RPC案例新建 streamdemo.proto客户端服务端总结gRPC四种通信模式 gRPC有四种通信⽅式,分别是:简单 RPC(Unary RPC)、服务端流式 RPC (…
文章目录
- gRPC四种通信模式
- RPC(Unary RPC)
- 服务端流RPC
- 客户端流RPC
- 双向流RPC
- 案例
- 新建 streamdemo.proto
- 客户端
- 服务端
- 总结
gRPC四种通信模式
gRPC有四种通信⽅式,分别是:简单 RPC(Unary RPC)、服务端流式 RPC (Server streaming RPC)、客户端流式 RPC (Clientstreaming RPC)、双向流式 RPC(Bi-directional streaming RPC)。它们主要有以下特点:
服务类型 | 特点 |
---|---|
简单 RPC | ⼀般的rpc调⽤,传⼊⼀个请求对象,返回⼀个返回对象 |
服务端流式 RPC | 传⼊⼀个请求对象,服务端可以返回多个结果对象 |
客户端流式 RPC | 客户端传⼊多个请求对象,服务端返回⼀个结果对象 |
双向流式 RPC | 结合客户端流式RPC和服务端流式RPC,可以传⼊多个请求对象,返回多个结果对 |
RPC(Unary RPC)
简单rpc 这就是⼀般的rpc调⽤,⼀个请求对象对应⼀个返回对象
客户端发起⼀次请求,服务端响应⼀个数据,即标准RPC通信。
这种模式,⼀个每⼀次都是发起⼀个独⽴的tcp连接,⾛⼀次三次握⼿和四次挥⼿!
这个就是我们基础案例的示例,模式图如下
服务端流RPC
服务端流式rpc ⼀个请求对象,服务端可以传回多个结果对象
服务端流 RPC 下,客户端发出⼀个请求,但不会⽴即得到⼀个响应,⽽是在服务端与客户端之间建⽴⼀个单向的流,服务端可以随时向流
中写⼊多个响应消息,最后主动关闭流,⽽客户端需要监听这个流,不断获取响应直到流关闭
应⽤场景举例:
典型的例⼦是客户端向服务端发送⼀个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端
客户端流RPC
客户端流式rpc 客户端传⼊多个请求对象,服务端返回⼀个响应结果
应用场景如:物联⽹终端向服务器报送数据
双向流RPC
双向流式rpc 结合客户端流式rpc和服务端流式rpc,可以传⼊多个对象,返回多个响应对象
应⽤场景:聊天应⽤
案例
新建 streamdemo.proto
syntax = "proto3";
option go_package = ".;proto";
// 定义一个服务,gRPC自有的,它需要用grpc插件生成,也就是咱们安装的那个插件
service Greeter{// 服务端流模式rpc GetStream(StreamRequestData) returns(stream StreamResponseData);// 客户端流模式rpc PutStream(stream StreamRequestData) returns(StreamResponseData);// 双向流模式rpc AllStream(stream StreamRequestData) returns(stream StreamResponseData);
}// 类似于go的结构体,可以定义属性
message StreamRequestData {string data = 1;
}
// 定义一个响应的类型
message StreamResponseData {string data = 1;
}
执行命令,生成go文件
protoc --go_out=. --go_opt=paths=source_relative ./streamdemo.protoprotoc --go-grpc_out=. --go-grpc_opt=require_unimplemented_servers=false --go-grpc_opt=paths=source_relative ./streamdemo.proto
客户端
package mainimport ("context""fmt""go_test_learn/grpc_stream/proto""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""sync""time"
)func main() {conn, err := grpc.Dial("127.0.0.1:50052", grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {panic(err)}defer conn.Close()client := proto.NewGreeterClient(conn)// ******服务端流模式示例***start******//res,err:=client.GetStream(context.Background(),&proto.StreamRequestData{Data: "开始要时间"})//if err!=nil{// panic(err)//}//for { // 开启死循环,不停接收数据// r,err:=res.Recv() // 本质就是socket接收数据// if err != nil {// fmt.Println("接收出错")// break// }// fmt.Println(r.Data)//}// ******服务端流模式示例***end******// ******客户端端流模式示例***start******//res, err := client.PutStream(context.Background())//if err != nil {// fmt.Println(err)// panic(err)//}//var i = 0//for {// res.Send(&proto.StreamRequestData{// Data: fmt.Sprintf("客户端当前时间为:%v", time.Now().Unix()),// })// time.Sleep(time.Second)// i++// if i == 10 {// break// }//}// ******客户端流模式示例***end******// ******双向流模式示例***start******req, err := client.AllStream(context.Background())wg := sync.WaitGroup{}wg.Add(2)// 开协程发送数据,发送10次go func() {for i := 0; i < 10; i++ {req.Send(&proto.StreamRequestData{Data: "客户端发送的数据",})time.Sleep(time.Second)}wg.Done()}()// 开协程接收数据,接收10次stream, err := client.AllStream(context.Background())if err != nil {panic(err)}wg := sync.WaitGroup{}wg.Add(2)// 开 goroutine 发送数据go func() {for i := 0; i < 10; i++ {stream.Send(&proto.StreamRequestData{Data: "客户端发送的数据",})time.Sleep(time.Second)}wg.Done()}()// 开goroutine 接收数据go func() {for i := 0; i < 10; i++ {recv, err := stream.Recv()if err != nil {panic(err)}fmt.Println(recv.Data)}wg.Done()}()wg.Wait()// ******双向流模式示例***end******}
服务端
package mainimport ("fmt""go_test_learn/grpc_stream/proto""google.golang.org/grpc""net""sync""time"
)type GreeterServer struct {
}// 服务端流模式
func (ser *GreeterServer) GetStream(request *proto.StreamRequestData, response proto.Greeter_GetStreamServer) error {fmt.Println(request.Data) // 打印了一下从客户端传入的数据var i = 0 // 定义一个数字,就发送10次for { // 死循环源源不断向客户端发送// 以流的方式向客户端发送数据response.Send(&proto.StreamResponseData{Data: fmt.Sprintf("当前服务器时间为:%v", time.Now().Unix()),})time.Sleep(time.Second) // 睡1s钟再发i++ //自增1if i == 10 { // i为10的时候结束break}}return nil
}// 客户端流模式
func (ser *GreeterServer) PutStream(request proto.Greeter_PutStreamServer) error {for {// 不断的接收并打印客户端发送过来的数据res, err := request.Recv()if err != nil {return err}fmt.Println(res.Data)}return nil
}// 双向流模式
func (ser *GreeterServer) AllStream(request proto.Greeter_AllStreamServer) error {// 开启两个协程,一个接收数据,一个发送数据var wg=sync.WaitGroup{}wg.Add(2)go func() { // 发送数据for {err := request.Send(&proto.StreamResponseData{Data: "服务端给你的数据",})if err != nil {fmt.Println(err)break}time.Sleep(time.Second) // 睡1s发送一次}wg.Done()}()go func() { // 不停接收数据for {res, err := request.Recv()if err != nil {fmt.Println(err)break}fmt.Println(res.Data)}wg.Done()}()wg.Wait()return nil
}func main() {// 创建一个监听tcp,50052端口lis, err := net.Listen("tcp", ":50052")if err != nil {panic(err)}// new一个grpc的serverser := grpc.NewServer()// 注册服务proto.RegisterGreeterServer(ser, &GreeterServer{})// 让grpc对外提供服务err = ser.Serve(lis)if err != nil {panic(err)}}
总结
gRPC设计为低延迟和⾼吞吐量通信。gRPC⾮常适⽤于效率⾄关重要的轻型微服务。点对点实时通信 - gRPC对双向流媒体提供出⾊的⽀持。
gRPC服务可以实时推送消息⽽⽆需轮询。多语⾔混合开发环境 - gRPC⼯具⽀持所有流⾏的开发语⾔,使gRPC成为多语⾔开发环境的理想选择。
⽹络受限环境 - 使⽤Protobuf(⼀种轻量级消息格式)序列化gRPC消息。gRPC消息始终⼩于等效的JSON消息