Как определить заголовки ответа для унарного rpc

В Go я хочу установить некоторые заголовки ответов из моей реализации обработчика rpc. В частности, я хочу установить некоторые заголовки, относящиеся к управлению кешем.

Однако, когда rpc определяется как унарный ответ, сигнатура метода, сгенерированная протоколом, включает только контекст запроса и сообщение запроса. Это контрастирует с кодом, сгенерированным из потокового ответа, который включает сообщение запроса и grpc.ServerStream.

Вот пример интерфейса, созданного протоколом:

type CmsServer interface {
  GetPost(context.Context, *PostRequest) (*Post, error)
  GetPosts(*GetPostsOptions, Cms_GetPostsServer) error
}

В этом примере GetPosts включает параметр Cms_GetPostsServer, который представляет собой grpc.ServerStream, который, по-видимому, включает методы для установки пользовательских заголовков ответов https://godoc.org/google.golang.org/grpc#ServerStream (я еще не пробовал это сделать, поправьте меня, если это не так).

Между тем, GetPost, похоже, не имеет возможности установить заголовки ответа, просто взглянув на сигнатуру метода (context.Context - это только контекст запроса, а не контекст ответа). Итак, как мне установить собственные заголовки ответа для унарного ответа?


person thurt    schedule 05.02.2018    source источник
comment
Вы уверены, что это точный интерфейс? Все методы обычно имеют вариативный набор CallOptions в конце (opts ...grpc.CallOption).   -  person JimB    schedule 06.02.2018
comment
@JimB Я вижу (opts ...grpc.CallOption) в клиентских методах, но не в серверных.   -  person thurt    schedule 06.02.2018
comment
Ах да, извините - у меня это было наоборот.   -  person JimB    schedule 06.02.2018


Ответы (1)


См. Отправка и получение метаданных - на стороне сервера

Контекст запроса содержит информацию для сопоставления запроса с соединением. Вы используете grpc.SetHeader или _ 2_ для записи дополнительных метаданных с сервера.

func (s *server) SomeRPC(ctx context.Context, in *pb.someRequest) (*pb.someResponse, error) {
    // create and send header
    header := metadata.Pairs("header-key", "val")
    grpc.SendHeader(ctx, header)
    // create and set trailer
    trailer := metadata.Pairs("trailer-key", "val")
    grpc.SetTrailer(ctx, trailer)
}
person JimB    schedule 05.02.2018
comment
Спасибо! это имеет смысл. из исходного кода grpc.SetHeader я вижу, что соединение с потоком все еще существует, но оно тайно прикреплено к контексту - person thurt; 06.02.2018