(Go) 比较 ws 循环中不断变化的变量
(Go) Comparing everchanging variable in ws loop
在一个接收消息并相应地处理它们的循环上工作,基本上是一个带有保持活动和身份验证的 websocket 回显器,我已经在保持活动部分停留了一段时间了。
这个概念很简单,当服务器启动时,我创建了一个带有自动收报机的 goroutine,并初始化了一个 uint64 指针,每次自动收报机计时(每 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
}
}
在这段代码中,i := atomic.LoadUint64(clockTicks) & 所有 if 块仅在发送 i 消息时 运行s(在 msg 上打印 "Keep Going."),这不是什么我想要,我希望代码段每次迭代 运行,并且 "Keep Going." & "Quit nao ..." 每次 clockTicks 递增时触发
这是重要的代码部分,我使用的是 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 正在阻塞它,并且他对此很确定)
websocket 读取方法调用 network connection Read method 从网络获取数据。因为网络连接Read方法阻塞,webscocket方法也阻塞。
要发送 ping,请在写入循环中使用代码 as in the Gorilla chat example or run a separate goroutine for pings as in Gorilla command example。
在一个接收消息并相应地处理它们的循环上工作,基本上是一个带有保持活动和身份验证的 websocket 回显器,我已经在保持活动部分停留了一段时间了。
这个概念很简单,当服务器启动时,我创建了一个带有自动收报机的 goroutine,并初始化了一个 uint64 指针,每次自动收报机计时(每 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
}
}
在这段代码中,i := atomic.LoadUint64(clockTicks) & 所有 if 块仅在发送 i 消息时 运行s(在 msg 上打印 "Keep Going."),这不是什么我想要,我希望代码段每次迭代 运行,并且 "Keep Going." & "Quit nao ..." 每次 clockTicks 递增时触发
这是重要的代码部分,我使用的是 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 正在阻塞它,并且他对此很确定)
websocket 读取方法调用 network connection Read method 从网络获取数据。因为网络连接Read方法阻塞,webscocket方法也阻塞。
要发送 ping,请在写入循环中使用代码 as in the Gorilla chat example or run a separate goroutine for pings as in Gorilla command example。