通过特定端口发送GRPC通信

我正在运行在特定端口上侦听的GRPC服务器(服务器A)。 我希望能够将通信发送到另一台服务器(服务器B),并让服务器B记录服务器A连接的传入地址,以便以后可以与服务器A联系。</ p>

打开 服务器A,我在端口上侦听并创建了这样的上下文:</ p>

  lis,err:= net.Listen(“ tcp”,“ 0.0.0.0:6000”)

ctx,取消:= context.WithTimeout(context.Background(),
10000 * time.Millisecond)
</ code> </ pre>

然后按如下所示创建连接:</ p>

 连接,err = grpc.DialContext(ctx,server2Address,
grpc.WithInsecure(),grpc.WithBlock())
</ code> </ pre>
\ n

在最终向服务器B上的端点发送消息之前,该端点尝试读取服务器A的传入连接的IP地址</ p>

  info,_:= peer.FromContext  (ctx)
fmt.Printf(info.Addr.String())//返回一个随机端口,不是6000,
</ code> </ pre>

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

展开原文

原文

I am running a GRPC server (Server A) listening on a specific port. I want to be able to send a communication to another server (Server B), and have Server B record the incoming address of Server A's connection so that it may later contact Server A.

On Server A, I listen on a port and create a context like such:

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

Then create a connection like so:

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

Before finally sending a message to an endpoint on Server B, which attempts to read the IP address of Server A's incoming connection

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

However, the resulting port printed by Server B is random, like 62056 as opposed to 6000 as intended. My assumption is that, on Server A, GRPC dials from a random port - is it possible to force GRPC to dial from port 6000 as opposed to a random port?

duanchi4184
duanchi4184 为什么没有在知名端口的serverA上托管gRPC服务,以便服务器B可以直接回话?您是否要执行此操作以处理特定交易并需要维持交易状态?如果是这样,我将使用一些令牌交换,而不是涉及一些潜在的复杂通信路径。
一年多之前 回复
doushi4864
doushi4864 服务器A知道服务器B的地址和端口,但不知道服务器B的地址和端口。我需要以某种方式通知服务器B服务器A的地址和端口,以便服务器B将来可以与服务器A进行通信。因此,我试图从服务器A到服务器的传入通信提供的上下文中抓取该信息。服务器B,但是,端口号不正确,因此该帖子。
一年多之前 回复
doutuo3575
doutuo3575 为什么要关心客户端的端口号?您要在此处解决的更大问题是什么?
一年多之前 回复

1个回答

You can specify the source port like this:

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)
    }))

However if your server is listening on the same port this will result in an error:

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

A different approach would be to pass the address as metadata. On the client you do:

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",
})

And on the server:

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
}

And a third approach would be to use streaming.

douwen8424
douwen8424 到处都是很棒的信息。
大约一年之前 回复
立即提问
相关内容推荐