I'm building a desktop application (Go + gRPC) to analyze YouTube Live Chat in real time. The REST endpoint liveChatMessages.list works, but I want to switch to liveChatMessages.streamList because according to the documentation it has lower quota usage.
I successfully established a gRPC connection and I receive chat messages normally, but after a few seconds the stream always closes with an EOF.
❓ Problem
The stream starts normally, receives a few responses, and then Recv() returns:
EOF
I don’t see any description in the documentation indicating that Google closes the stream periodically, or that clients must reconnect manually.
func (g *GrpcStreamListener) startStreaming(
ctx context.Context,
liveChatId string,
onMessage func(*LiveChatMessage),
) error {
streamCtx, cancel := context.WithCancel(ctx)
g.cancel = cancel
req := &LiveChatMessageListRequest{
LiveChatId: &liveChatId,
Hl: proto.String("pt-BR"),
ProfileImageSize: proto.Uint32(64),
MaxResults: proto.Uint32(20),
PageToken: g.nextPageToken,
Part: []string{"id", "snippet", "authorDetails"},
}
stream, err := g.client.StreamList(streamCtx, req)
if err != nil {
return fmt.Errorf("failed to start stream: %w", err)
}
g.stream = stream
go g.receiveMessages(onMessage)
return nil
}
func (g *GrpcStreamListener) receiveMessages(onMessage func(*LiveChatMessage)) {
for {
response, err := g.stream.Recv()
if err != nil {
// After a few seconds, err = EOF
log.Printf("stream error: %v", err)
break
}
g.nextPageToken = response.NextPageToken
for _, msg := range response.GetItems() {
onMessage(msg)
}
}
}
Google closes the stream by sending EOF after 5–10 seconds.
❓ Question
Is this the expected behavior? Does YouTube intentionally close the streamList connection after a short period and require clients to reconnect? Or is my implementation missing something?
If anyone has a working implementation or has already dealt with this EOF issue, any guidance is appreciated.