go - 在第一个客户端到服务器请求和响应之后“超出上下文截止日期”
问题描述
在一个简单的 gRPC 示例中,我连接到服务器,请求发送一条文本消息,然后返回一条成功消息。服务器上线后,第一个客户端请求成功,没有错误。
但是,在第一次尝试之后,每个后续请求(与第一次相同)都会返回此错误,并且不会返回响应作为结果(仍然发送文本消息,但不会发回生成的 ID):
rpc error: code = DeadlineExceeded desc = context deadline exceeded
稍微调试了一下,发现报错
func (c *messageSchedulerClient) SendText(ctx context.Context, in *TextRequest, opts ...grpc.CallOption) (*MessageReply, error) {
...
err := c.cc.Invoke(ctx, "/communication.MessageScheduler/SendText", in, out, opts...)
...
return nil, err
}
返回
rpc error: code = DeadlineExceeded desc = context deadline exceeded
这是我的客户代码:
func main() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
c := pb.NewMessageSchedulerClient(conn)
var r *pb.MessageReply
r, err = pbSendText(c, false)
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetId())
err = conn.Close()
if err != nil {
log.Printf("Connection Close Error: %v", err)
}
return
}
func pbSendText(c pb.MessageSchedulerClient, instant bool) (*pb.MessageReply, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second * 5)
minute := timestamppb.New(time.Now().Add(time.Second * 30))
r, err := c.SendText(ctx, &pb.TextRequest{})
if err != nil {
log.Printf("DEBUG MESSAGE: Error after c.SendText(ctx, in): %v", err)
}
cancel()
return r, err
}
服务器代码是...
func (s *MessageServer) SendText(ctx context.Context, in *pb.TextRequest) (*pb.MessageReply, error) {
return &pb.MessageReply{Id: GeneratePublicId()}, nil
}
func GrpcServe() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterMessageSchedulerServer(s, &MessageServer{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
return
}
const Alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ0123457"
// executes instantly, O(n)
func GeneratePublicId() string {
return id.NewWithAlphabet(Alphabet)
}
我尝试将上下文从 .Background 更改为 .TODO。不工作。我敢肯定,这很简单,以至于我错过了。
同样,我第一次从客户端执行应用程序时,它可以工作。但是在第一次客户端应用程序执行之后,意味着应用程序执行及以后——直到我重新启动 gRPC 服务器,它给了我错误。
GeneratePublicId 函数几乎立即执行,因为它是 O(n) 并使用随机数函数。
解决方案
推荐阅读
- r - 如何使用基本 R 滞后函数?
- intellij-idea - Intellij/Scalatest 无法开始测试
- caching - 将独立 redis 标记为只读
- c# - 使用 .NET Core Web API 3.1 进行基于 JWT 角色的授权时出现 403 错误
- ios - Swift 用特殊关键字标记枚举元素
- python - 如何组合两个数据框并自然地对混合字母数字类型的列进行排序?
- html - 引导 div 错位
- javascript - 希望将 Tabulator 和 Wavesurfer.js 波形图片组合成单独的行
- python - UnicodeDecodeError:“utf-8”编解码器无法解码位置 0 中的字节 0xb0:无效的起始字节
- spring - spring data jpa和jpa实现