Golang gRPC双向流式传输支持实时交互,通过定义protobuf服务、生成代码、实现服务器和客户端完成通信,示例中客户端发送消息服务器回显;需处理流中错误,可采用重试或断路器模式;通过TLS和JWT实现身份验证与授权;性能优化包括启用压缩、调整缓冲区、使用连接池、负载均衡及HTTP/3协议提升传输效率。

Golang gRPC 流式传输允许客户端和服务器之间进行连续的数据交换,而不仅仅是传统的请求-响应模式。双向流式传输则允许双方同时发送和接收数据,极大地增强了实时性和交互性。
解决方案
下面是一个简单的 Golang gRPC 双向流式传输的示例。
1. 定义 Protocol Buffer (protobuf) 服务
立即学习“go语言免费学习笔记(深入)”;
首先,我们需要定义一个 protobuf 文件,描述我们的服务和消息格式。
syntax = "proto3";
package stream;
option go_package = "./stream";
service StreamService {
rpc RouteChat (stream RouteNote) returns (stream RouteNote) {}
}
message RouteNote {
string message = 1;
}这个protobuf文件定义了一个
StreamService
RouteChat
RouteChat
RouteNote
2. 生成 gRPC 代码
使用
protoc
protoc --go_out=. --go-grpc_out=. stream.proto
这将生成
stream.pb.go
stream_grpc.pb.go
3. 实现 gRPC 服务器
接下来,我们需要实现 gRPC 服务器。
package main
import (
"context"
"fmt"
"io"
"log"
"net"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
pb "example.com/stream" // 替换成你的模块路径
)
type server struct {
pb.UnimplementedStreamServiceServer
}
func (s *server) RouteChat(stream pb.StreamService_RouteChatServer) error {
for {
note, err := stream.Recv()
if err == io.EOF {
return nil
}
if err != nil {
return err
}
log.Printf("Received message: %v", note.Message)
// Echo back the message
resp := &pb.RouteNote{Message: "Server received: " + note.Message}
if err := stream.Send(resp); err != nil {
return err
}
}
}
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterStreamServiceServer(s, &server{})
reflection.Register(s)
fmt.Println("Server listening on :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}这段代码创建了一个 gRPC 服务器,监听 50051 端口,并注册了
StreamService
RouteChat
4. 实现 gRPC 客户端
现在,我们需要实现 gRPC 客户端。
package main
import (
"context"
"fmt"
"io"
"log"
"time"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "example.com/stream" // 替换成你的模块路径
)
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewStreamServiceClient(conn)
stream, err := client.RouteChat(context.Background())
if err != nil {
log.Fatalf("could not greet: %v", err)
}
// Send messages
messages := []string{"Hello", "World", "How", "Are", "You"}
for _, message := range messages {
req := &pb.RouteNote{Message: message}
if err := stream.Send(req); err != nil {
log.Fatalf("failed to send a note: %v", err)
}
log.Printf("Sent message: %v", message)
time.Sleep(time.Second) // Simulate some delay
}
// Close the stream and receive responses
if err := stream.CloseSend(); err != nil {
log.Fatalf("failed to close stream: %v", err)
}
for {
resp, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatalf("failed to receive a note: %v", err)
}
log.Printf("Received message: %v", resp.Message)
}
fmt.Println("Client finished")
}这段代码连接到 gRPC 服务器,创建
StreamService
RouteChat
5. 运行示例
首先,启动 gRPC 服务器。
go run server.go
然后,启动 gRPC 客户端。
go run client.go
你将在服务器和客户端的控制台中看到消息的发送和接收。
在流式传输中,错误处理至关重要。服务器和客户端都需要能够优雅地处理连接中断、数据损坏或其他意外情况。在服务器端,
RouteChat
stream.Recv()
stream.Send()
安全性是另一个需要考虑的重要方面。gRPC 提供了多种身份验证机制,例如 TLS、JWT 和自定义身份验证。对于流式传输,通常使用 TLS 来加密通信,并使用 JWT 或其他身份验证方法来验证客户端的身份。服务器可以在
RouteChat
gRPC 流的性能受到多种因素的影响,例如网络延迟、消息大小和服务器的负载。为了优化性能,可以采取以下措施:
例如,可以通过设置
grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name))
以上就是GolangRPC流式传输与双向通信示例的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号