如何运行心跳函数
How to run a heartbeat function
我看到了很多关于如何定期 运行 函数的问题。 问题?他们都阻止了程序继续进行。
我需要什么?
我有一个 websocket,我有一个 for {}
,它一直在读取消息,现在每 10 秒我需要 运行 调用心跳函数,而不会中断程序或停止阅读聊天。
我正在考虑使用一些方法,但其中 none 似乎 clean/nice 使用渠道,但我认为更有经验的人可能有更好更简单的方法。
我正在使用类似的东西,但它永远不会到达函数的末尾 return 我需要让程序继续。
timerCh := time.Tick(time.Duration(10) * time.Second)
for range timerCh {
go Heartbeat(ws)
}
return ws
我正在寻找一种能够每 10 秒调用 Heartbeat 的方法,而无需:
- 每次读取传入的 websocket 连接时重复调用它
- 没有锁定程序。
一些上下文,
这是用于桥接聊天,所以我打开一个 websocket,继续阅读,并且只在聊天消息时发送到另一个聊天,同时我需要发送心跳而不锁定它。
我现在有什么?
现在一切正常,但大约 30 秒后我的 websocket 关闭:
2020/07/01 20:59:09 Error read: websocket: close 1000 (normal)
编辑:接受@JimB 的回答!这只是为了表明计时器应该在 main
goroutine 之外进行管理。
您的检测信号函数应该管理自己的计时器。这样的事情应该有效:
package main
import (
"fmt"
"time"
)
func main() {
go heartbeat()
for i := 0; i < 10; i++ {
fmt.Println("main is still going")
time.Sleep(time.Second * 3)
}
}
func heartbeat() {
for {
timer := time.After(time.Second * 10)
<-timer
fmt.Println("heartbeat happened!")
}
}
此示例将每 3 秒从 main
打印一次,每 10
从心跳打印一次,并将在 30 秒后终止。
您将希望能够关闭自动收报机,所以不要使用 time.Tick
,而是使用 time.NewTicker
。
如果将带有代码的整个 for 循环移动到一个 goroutine 中,它不会阻塞主 goroutine。
go func() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for range ticker.C {
Heartbeat(ws)
// return on error or cancellation
}
}()
我看到了很多关于如何定期 运行 函数的问题。 问题?他们都阻止了程序继续进行。
我需要什么?
我有一个 websocket,我有一个 for {}
,它一直在读取消息,现在每 10 秒我需要 运行 调用心跳函数,而不会中断程序或停止阅读聊天。
我正在考虑使用一些方法,但其中 none 似乎 clean/nice 使用渠道,但我认为更有经验的人可能有更好更简单的方法。
我正在使用类似的东西,但它永远不会到达函数的末尾 return 我需要让程序继续。
timerCh := time.Tick(time.Duration(10) * time.Second)
for range timerCh {
go Heartbeat(ws)
}
return ws
我正在寻找一种能够每 10 秒调用 Heartbeat 的方法,而无需:
- 每次读取传入的 websocket 连接时重复调用它
- 没有锁定程序。
一些上下文, 这是用于桥接聊天,所以我打开一个 websocket,继续阅读,并且只在聊天消息时发送到另一个聊天,同时我需要发送心跳而不锁定它。 我现在有什么? 现在一切正常,但大约 30 秒后我的 websocket 关闭:
2020/07/01 20:59:09 Error read: websocket: close 1000 (normal)
编辑:接受@JimB 的回答!这只是为了表明计时器应该在 main
goroutine 之外进行管理。
您的检测信号函数应该管理自己的计时器。这样的事情应该有效:
package main
import (
"fmt"
"time"
)
func main() {
go heartbeat()
for i := 0; i < 10; i++ {
fmt.Println("main is still going")
time.Sleep(time.Second * 3)
}
}
func heartbeat() {
for {
timer := time.After(time.Second * 10)
<-timer
fmt.Println("heartbeat happened!")
}
}
此示例将每 3 秒从 main
打印一次,每 10
从心跳打印一次,并将在 30 秒后终止。
您将希望能够关闭自动收报机,所以不要使用 time.Tick
,而是使用 time.NewTicker
。
如果将带有代码的整个 for 循环移动到一个 goroutine 中,它不会阻塞主 goroutine。
go func() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for range ticker.C {
Heartbeat(ws)
// return on error or cancellation
}
}()