如何保存 GRPC 流以便重复使用

huangapple go评论91阅读模式
英文:

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 &lt;-conn.error

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

huangapple
  • 本文由 发表于 2016年4月29日 01:03:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/36921131.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定