dongmacuo1193 2015-11-01 18:41 采纳率: 0%
浏览 51
已采纳

(转到)在ws循环中比较不断变化的变量

Working on a loop that receives messages and processes them accordingly, basically a websocket echo-er with keep-alives and authentication, and I've been stuck in the keep-alive part for a little while now.

The concept is simple, when the server starts I create a goroutine with a ticker, and I initialize a uint64 pointer, each time that ticker ticks (every 2 seconds), I increment the pointer with atomic.AddUint64(clockTicks, 1), then for each websocket connection goroutine, I check the variable every tick with a compare and atomic.LoadUint64(clockTicks), and I send a ping/pong message.

Edit: Seems like something is blocking the for loop until a message is received, result:

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
        }
    }

In this snippet, i := atomic.LoadUint64(clockTicks) & all the if block only runs when i message is sent (Prints "Keep Going." on msg), which is not what I want, I want the snippet to run every for iteration, and "Keep Going." & "Quit nao ..." to trigger everytime clockTicks is incremented

Here's the important code parts, I'm using Go and Gorilla's Websockets library:

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
    }

    ...

}

Edit 2: Someone in IRC suggested that maybe ws.ReadMessage is blocking, but I'm not really sure (He says ioutil.ReadAll used in ws.ReadMessage implementation is blocking it, and he's pretty sure about it)

  • 写回答

1条回答 默认 最新

  • doufeiqiong3515 2015-11-01 19:38
    关注

    The websocket read methods call the network connection Read method to get data from the network. Because the network connection Read method blocks, the webscocket methods also block.

    To send pings, use a ticker in the write loop as in the Gorilla chat example or run a separate goroutine for pings as in Gorilla command example.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用三极管设计—个共射极放大电路
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示