Как обнаружить отмененное / потерянное / закрытое соединение в облачном режиме с потоковой передачей gRPC server?

# #go #google-cloud-run

#Вперед #google-cloud-run

Вопрос:

У меня есть потоковый RPC на стороне сервера, размещенный в облачном режиме Google.

Со следующим определением proto:

 syntax = "proto3";

package test.v1;

service MyService {
    // Subscribe to a stream of events.
    rpc Subscribe (SubscribeRequest) returns (stream SubscribeResponse) {}
}

message SubscribeRequest {
}

message SubscribeResponse {
}
 

Используя BloomRPC / grpcurl, когда я останавливаю метод, я получаю stream.Context().Done() событие, которое я могу использовать для корректной остановки определенных задач. Вот пример метода Suscribe:

 func (s *myService) Subscribe(req *pb.SubscribeRequest, stream pb.Instruments_SubscribeServer) error {
    
    // Create a channel for this client.
    ch := make(chan *pb.SubscribeResponse)
    
    // Add the channel object 'ch' to a Global list of channels where we have a 'broadcaster' sending
    // messages to all connected clients.
    // TODO: pass to broadcaster client list.
    
    for {
        select {
        case <-stream.Context().Done():
            close(ch)
            fmt.Println("Removed client from global list of channels")
            return nil
        case res := <-ch:
            _ = stream.Send(res)
        }
    }
}
 

На стороне клиента, когда я тестирую службу локально (т. Е. Запускаю локальный сервер gRPC в Golang), используя BloomRPC / grpcurl, я получаю сообщение на stream.Context().Done() канале всякий раз, когда я останавливаю соединение BloomRPC / grpcurl. Это ожидаемое поведение.

Однако, запустив точно такой же код при облачном запуске таким же образом (через BloomRPC / grpcurl), я не получаю stream.Context().Done() сообщение — есть ли причина, по которой это будет отличаться при облачном запуске Google? Просматривая журналы облачных запусков, вызов метода Subscribe по существу «зависает», пока запрос не достигнет своего тайм-аута.

Ответ №1:

Мне нужно было включить HTTP / 2 подключения в облачном режиме, чтобы это сработало.