在没有可用连接的情况下创建一个删除数据的goroutine / channel

时间:2018-01-24 02:17:57

标签: go channel goroutine

我是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()

0 个答案:

没有答案