Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save an GRPC stream for reusement

I have an GRPC server which provides an function and returns a stream. I want to save the stream onto a map[string]grpc.Stream - this works so far.

My problem is that the stream gets closed after the function that returns the stream finishes its logic.

This is, what I have so far:

func (s *server) CheckConnection(initMessage *LighterGRPC.InitMessage, stream LighterGRPC.Lighter_CheckConnectionServer) error {
    //Do something magic
    streams[initMessage.DeviceID] = stream

    error := stream.Send(&LighterGRPC.ColorMessage{DATA})
    if error {
        log.Println(error)
    }

    //Tried
    //for { }

    return error
}

I already tried to let the function never return anything with an for {} before the return (as commented in the code above), but that didn't helped and I don't think, that this could be the solution.

Is there a way to leave the stream open so I can send data later in runtime over it to the client?

like image 393
JSF Avatar asked Apr 28 '16 17:04

JSF


1 Answers

For those of you, who may encounter the same problem, here is the quick solution. Basically, you need to wrap your stream in a struct, so that there is an error chan. Return will block until there is an error occuring when you execute stream.Send()

type Connection struct {
    stream LighterGRPC.Lighter_CheckConnectionServer
    error  chan error
}

You map will be like:

type Server struct {
    ....
    conns map[string]Connection
}

And your RPC for creating a stream at the end should be like:

conn := Connection{
    stream: stream,
    error:  make(chan error),
}
s.conns[initMessage.DeviceID] = conn

return <-conn.error

That way your stream will be stored in a map while being "active".

like image 117
ysakiyev Avatar answered Sep 28 '22 06:09

ysakiyev