通过特定端口发送GRPC通信

  • 本文关键字:GRPC 通信 go grpc
  • 更新时间 :
  • 英文 :


我在特定端口上运行grpc服务器(服务器A(。我希望能够将通信发送到另一台服务器(服务器B(,并让服务器B记录服务器A连接的传入地址,以便以后联系服务器A。

在服务器A上,我在端口上收听并创建这样的上下文:

lis, err := net.Listen("tcp", "0.0.0.0:6000")
ctx, cancel := context.WithTimeout(context.Background(),
    10000*time.Millisecond)

然后创建这样的连接:

connection, err = grpc.DialContext(ctx, server2Address,
grpc.WithInsecure(), grpc.WithBlock())

在最终将消息发送到服务器B上的端点之前,该消息试图读取服务器A传入连接的IP地址

info, _ := peer.FromContext(ctx)
fmt.Printf(info.Addr.String()) // Returns a random port, NOT 6000,

但是,服务器B打印的结果端口是随机的,例如62056,而不是预期的6000。我的假设是,在服务器A上,来自随机端口的GRPC拨号 - 是否可以强迫GRPC从端口6000拨号而不是随机端口?

您可以像这样指定源端口:

cc, err := grpc.Dial("127.0.0.1:6001", grpc.WithInsecure(),
    grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
        dst, err := net.ResolveTCPAddr("tcp", addr)
        if err != nil {
            return nil, err
        }
        src := &net.TCPAddr{
            IP:   net.ParseIP("127.0.0.1"),
            Port: 6000,
        }
        return net.DialTCP("tcp", src, dst)
    }))

但是,如果您的服务器在同一端口上收听,这将导致错误:

panic: dial tcp 127.0.0.1:6000->127.0.0.1:6001: bind: address already in use

另一种方法是将地址作为元数据传递。在客户上您要做:

ctx := context.Background()
ctx = metadata.NewOutgoingContext(ctx, metadata.Pairs("address", "127.0.0.1:6000"))
res, err := grpc_health_v1.NewHealthClient(cc).Check(ctx, &grpc_health_v1.HealthCheckRequest{
    Service: "test",
})

和在服务器上:

func (s *server) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
    if md, ok := metadata.FromIncomingContext(ctx); ok {
        addr := md.Get("address")
        // addr == "127.0.0.1:6000"
    }
    return &grpc_health_v1.HealthCheckResponse{
        Status: grpc_health_v1.HealthCheckResponse_SERVING,
    }, nil
}

和第三种方法是使用流。

最新更新