【问题标题】:(Go) Comparing everchanging variable in ws loop(Go) 比较 ws 循环中不断变化的变量
【发布时间】:2015-11-02 03:44:29
【问题描述】:

处理一个接收消息并相应地处理它们的循环,基本上是一个具有保持活动和身份验证的 websocket echo-er,我已经在保持活动部分停留了一段时间。

这个概念很简单,当服务器启动时,我创建一个带有ticker的goroutine,并初始化一个uint64指针,每次ticker滴答声(每2秒),我用atomic.AddUint64(clockTicks,1 ),然后对于每个 websocket 连接 goroutine,我使用比较和 atomic.LoadUint64(clockTicks) 来检查每个刻度的变量,然后发送一个 ping/pong 消息。

编辑:似乎有什么东西阻塞了 for 循环,直到收到消息,结果:

i := atomic.LoadUint64(clockTicks)
    if i != cur {
        cur = i
        if act != true {
            fmt.Println("Quit Nao U filthy bot.")
            return
        } else {
            fmt.Println("Keep Going.")
            act = false
        }
    }

在这个 sn-p 中,i := atomic.LoadUint64(clockTicks) & 所有 if 块仅在发送 i 消息时运行(在 msg 上打印“Keep Going.”),这不是我想要的,我想要运行每个迭代的 sn-p 和“继续前进”。 & "Quit nao ..." 以在每次时钟刻度增加时触发

这是重要的代码部分,我正在使用 Go 和 Gorilla 的 Websockets 库:

func Clock() {
clockTicks = new(uint64)
*clockTicks = 0
clock := time.NewTicker(authIntervals).C
for {
    <-clock
    atomic.AddUint64(clockTicks, 1)
}
}

var wsu = websocket.Upgrader{
ReadBufferSize:  1024,
WriteBufferSize: 1024,
CheckOrigin:     OriginHandler,
}

func serveWS(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
    http.Error(w, "Method not allowed", 405)
    return
}

ws, err := wsu.Upgrade(w, r, nil)
if err != nil {
    fmt.Println(err)
    return
}

defer ws.Close()
cur := atomic.LoadUint64(clockTicks)
var act, val = true, false
for {
    i := atomic.LoadUint64(clockTicks)
    if i != cur { /* Only triggers when I receive a msg */
        cur = i
        if act != true {
            fmt.Println("Quit Nao U filthy bot.")
            return
        } else {
            fmt.Println("Keep Going.")
            act = false
        }
    }

    mtype, p, err := ws.ReadMessage()
    if err != nil {
        return
    }

    ...

}

编辑 2:IRC 中有人建议可能 ws.ReadMessage 正在阻塞,但我不太确定(他说 ws.ReadMessage 实现中使用的 ioutil.ReadAll 正在阻塞它,他对此非常确定)

【问题讨论】:

    标签: go websocket gorilla


    【解决方案1】:

    websocket 读取方法调用network connection Read method 从网络获取数据。因为网络连接Read方法阻塞了,webscocket方法也阻塞了。

    若要发送 ping,请在写入循环中使用自动收录器 as in the Gorilla chat example 或为 ping as in Gorilla command example 运行单独的 goroutine。

    【讨论】:

    • 有没有不阻塞的接收消息的方法?
    • @Whiteclaws 没有阻塞是不可能从网络连接中获取数据的。您可以编写一个读取循环,将消息发送到一个通道,该通道上的接收器使用 select 来避免阻塞(请参阅 Gorilla 聊天示例)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多