我是goroutines的新手,并试图找出组织此代码的惯用方法。我的程序将生成异步状态事件,我想通过websocket传输到服务器。现在我有一个全局频道messagesToServer
来接收状态消息。我们的想法是,如果我们当前打开了websocket,它将发送数据,或者如果与服务器的连接当前关闭或不可用,则会悄悄地丢弃它。
相关摘要如下。我不喜欢非阻塞发送 - 如果由于某种原因我的作家goroutine需要一段时间来处理消息我认为它可能最终会毫无理由地快速丢弃第二条消息?
但是如果我使用阻止发送,sendStatusToServer
可以阻止在连接脱机时不应阻止的内容。我可以尝试跟踪连接/断开连接状态,但如果在断开连接的同时发送了一条消息,我认为会有竞争条件。
我能写一个整洁的方式吗?
var (
messagesToServer chan common.StationStatus
)
// ...
func sendStatusToServer(msg common.StationStatus) {
// Must be non-blocking in case we're not connected
select {
case messagesToServer <- msg:
break
default:
break
}
}
// ...
// after making websocket connection
log.Println("Connected to central server");
finished := make(chan struct{})
// Writer
go func() {
for {
select {
case msg := <-messagesToServer:
var buff bytes.Buffer
enc := gob.NewEncoder(&buff)
err = enc.Encode(msg)
conn.WriteMessage(websocket.BinaryMessage, buff.Bytes()); // ignore errors by design
case <-finished:
return;
}
}
}()
// Reader as busy loop on this goroutine
for {
messageType, p, err := conn.ReadMessage()