Как определить отключенного клиента в gRPC? - PullRequest
2 голосов
/ 02 мая 2019

Я создаю API, используя gRPC, и на стороне сервера я хочу получать уведомление, когда клиент отключается, идентифицировать его и выполнять некоторые задачи на его основе.

До сих пор мне удавалось обнаружить отключение клиента, используя grpc.StatsHandler метод HandleConn. Я попытался передать значения, используя контекст, но к ним нельзя получить доступ со стороны сервера.

Клиентская сторона:

conn, err := grpc.DialContext(
    context.WithValue(context.Background(), "user_id", 1234),
    address,
    grpc.WithInsecure(),
)

Сторона сервера:

// Build stats handler
type serverStats struct {}

func (h *serverStats) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
    return ctx
}

func (h *serverStats) HandleRPC(ctx context.Context, s stats.RPCStats) {}

func (h *serverStats) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context {
    return context.TODO()
}

func (h *serverStats) HandleConn(ctx context.Context, s stats.ConnStats) {
    fmt.Println(ctx.Value("user_id")) // Returns nil, can't access the value

    switch s.(type) {
    case *stats.ConnEnd:
        fmt.Println("client disconnected")
        break
    }
}


// Build server
s := grpc.NewServer(grpc.StatsHandler(&serverStats{}))

Я хочу получить доступ к значению, переданному со стороны клиента на стороне сервера. Как правильно сделать это, или есть какой-то другой способ идентифицировать клиента, который отключился?

1 Ответ

0 голосов
/ 02 мая 2019

Я попытался передать значения с помощью контекста, но к ним нельзя получить доступ со стороны сервера.

Вам необходимо явно задать поля метаданных для контекста клиента:

ctx := context.Background()
ctx = metadata.AppendToOutgoingContext(ctx, "user_id", "1234")
conn, err := grpc.DialContext(cxt, address)

На стороне сервера вы можете получить их следующим образом:

md, ok := metadata.FromIncomingContext(ctx)

Как правильно это сделать, или есть какой-то другой способ идентифицировать клиента, который отключился?

Это действительно зависит от вашего варианта использования.Я думаю, что GRPC Stats API хорош для некоторых простых задач (например, для вычисления задержки или агрегирования сетевой статистики), но он не очень полезен, когда некоторая бизнес-логика должна работать, когда клиент уходит.Для этого я бы предложил использовать defer вызовы в обработчиках GRPC.Еще один вариант - реализовать собственный перехватчик GRPC.

...