首页 > 解决方案 > 在第一个客户端到服务器请求和响应之后“超出上下文截止日期”

问题描述

在一个简单的 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) 并使用随机数函数。

标签: gogrpc

解决方案


推荐阅读