根据gRPC文档,客户可以指定deadlines以确定客户端在退出DEADLINE_EXCEEDED
错误之前在服务器上等待的时间。该文档提到不同的语言具有不同的实现,并且某些语言没有默认值。
确实,快速CTRL + F用于"截止日期"在Go gRPC documentation上显示没有结果。我发现的是TCP连接拨号器上的WithTimeout
。
实施如下(来自helloworld example):
package main
import (
"log"
"os"
"time"
"golang.org/x/net/context"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
)
const (
address = "localhost:50051"
defaultName = "world"
deadline = 20
)
func main() {
// Set up a connection to the server with a timeout
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithTimeout(time.Duration(deadline)*time.Second)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
}
仅当客户端在20秒后无法连接时,代码才会引发错误。输出结果如下:
2016/05/24 09:02:54 grpc: Conn.resetTransport failed to create client transport: connection error: desc = "transport: dial tcp [::1]:3265: getsockopt: connection refused"; Reconnecting to "localhost:3265"
2016/05/24 09:02:54 Failed to dial localhost:3265: grpc: timed out trying to connect; please retry.
2016/05/24 09:02:54 could not greet: rpc error: code = 2 desc = grpc: the client connection is closing
正如问题标题所述,我正在使用的系统是点对点的,因此没有中央服务器,总是服务器,因此gRPC实现的重试系统非常棒。但是,我实际上是在寻找最后期限,因为如果遥控器连接了,但服务器需要>响应20秒,WithTimeout
上下文中不会引发任何异常。
对我来说完全胜利的是超时/截止日期系统,其中:
我的感觉是,我需要一些连接管理和gRPC截止日期管理的组合。有谁知道如何在Go中实现截止日期?
答案 0 :(得分:2)
根据context
的WithTimeout
示例
package main
import (
"context"
"fmt"
"time"
)
func main() {
// Pass a context with a timeout to tell a blocking function that it
// should abandon its work after the timeout elapses.
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
select {
case <-time.After(1 * time.Second):
fmt.Println("overslept")
case <-ctx.Done():
fmt.Println(ctx.Err()) // prints "context deadline exceeded"
}
}
您可以将helloworld example
客户端代码更改为100毫秒超时:
ctx, _ := context.WithTimeout(context.Background(), 100 * time.Millisecond)
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.Message)
答案 1 :(得分:0)
您应该更仔细地查看context
包。 GRPC是以背景为基础构建的。您可能需要grpc.Dial
上下文和client.SayHello
上下文来构建相关信息,但这应该是相当直接的。