英文:
How to save an GRPC stream for reusement
问题
我有一个提供函数并返回流的GRPC服务器。
我想将流保存到map[string]grpc.Stream
中-到目前为止这个方法是有效的。
我的问题是,在返回流的函数完成逻辑后,流会关闭。
这是我目前的代码:
func (s *server) CheckConnection(initMessage *LighterGRPC.InitMessage, stream LighterGRPC.Lighter_CheckConnectionServer) error {
//做一些魔法
streams[initMessage.DeviceID] = stream
error := stream.Send(&LighterGRPC.ColorMessage{DATA})
if error {
log.Println(error)
}
//尝试过
//for { }
return error
}
我已经尝试在返回之前使用for {}
让函数永远不返回任何内容(如上面的代码中所注释的),但这并没有帮助,我不认为这可能是解决方案。
有没有办法保持流开放,以便我可以在运行时稍后向客户端发送数据?
英文:
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?
答案1
得分: 2
对于可能遇到相同问题的人,这里是一个快速解决方案。基本上,你需要将你的流包装在一个结构体中,这样就会有一个错误通道。当你执行stream.Send()时,返回语句将会阻塞,直到发生错误。
type Connection struct {
stream LighterGRPC.Lighter_CheckConnectionServer
error chan error
}
你的映射将会是这样的:
type Server struct {
....
conns map[string]Connection
}
而你用于创建流的RPC应该是这样的:
conn := Connection{
stream: stream,
error: make(chan error),
}
s.conns[initMessage.DeviceID] = conn
return <-conn.error
这样,你的流将会在一个映射中被存储,同时保持"活动"状态。
英文:
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".
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论