Linux 如何运行heartbeat函数
我看到了大量关于如何定期运行函数的问题和回答。问题出在哪里?他们都锁定了程序,使其无法继续运行 我需要什么? 我有一个websocket和一个for{},它一直在读msg,现在和每10秒我需要运行一次对heartbeat函数的调用,而不会中断程序或停止阅读聊天。 我正在考虑使用一些方法,但没有一种方法在使用频道时看起来干净/好,但我认为更有经验的人可能会有一种更好、更简单的方法 我曾经使用过类似的东西,但它永远不会到达函数的末尾,返回程序继续运行所需的内容Linux 如何运行heartbeat函数,linux,go,websocket,gorilla,heartbeat,Linux,Go,Websocket,Gorilla,Heartbeat,我看到了大量关于如何定期运行函数的问题和回答。问题出在哪里?他们都锁定了程序,使其无法继续运行 我需要什么? 我有一个websocket和一个for{},它一直在读msg,现在和每10秒我需要运行一次对heartbeat函数的调用,而不会中断程序或停止阅读聊天。 我正在考虑使用一些方法,但没有一种方法在使用频道时看起来干净/好,但我认为更有经验的人可能会有一种更好、更简单的方法 我曾经使用过类似的东西,但它永远不会到达函数的末尾,返回程序继续运行所需的内容 timerCh := time.Tic
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的答案!这只是为了表明计时器应该在主goroutine之外进行管理
go func() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for range ticker.C {
Heartbeat(ws)
// return on error or cancellation
}
}()
您的heartbeat函数应该管理自己的计时器。像这样的方法应该会奏效:
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秒从heartbeat打印一次,并将在30秒后终止。编辑:按照@JimB的答案进行!这只是为了表明计时器应该在主goroutine之外进行管理
go func() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for range ticker.C {
Heartbeat(ws)
// return on error or cancellation
}
}()
您的heartbeat函数应该管理自己的计时器。像这样的方法应该会奏效:
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秒从heartbeat打印一次,并在30秒后终止。您希望能够关闭股票代码,因此不要使用time.Tick,而是使用time.NewTicker 如果您使用ticker将整个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
}
}()
您将希望能够关闭股票代码,因此不要使用time.Tick,而是使用time.NewTicker 如果您使用ticker将整个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
}
}()
为什么不把for循环放在goroutine中?从websocket读取的那个?因为它会持续不断地发出声音,我不希望这样,只希望每隔10秒左右。如果我添加一个计时器。滴答声然后停止主go例程…这不是你使用滴答器的原因,所以它只每10秒运行一次吗?你也应该有一些方法来取消这个,而且你不应该占用时间。勾选,因为正如文档所述,你不能关闭它嗯,也许这就是问题所在,我是一个新手,你能给我一个不会锁定我程序其余部分的示例吗?谢谢为什么不把for循环放在goroutine中?从websocket读取的那个?因为它会持续不断地发出声音,我不希望这样,只希望每隔10秒左右。如果我添加一个计时器。滴答声然后停止主go例程…这不是你使用滴答器的原因,所以它只每10秒运行一次吗?你也应该有一些方法来取消这个,而且你不应该占用时间。勾选,因为正如文档所述,你不能关闭它嗯,也许这就是问题所在,我是一个新手,你能给我一个不会锁定我程序其余部分的示例吗?Thanks@rek2:你不应该把时间用作睡眠,也不应该在这里使用睡眠。你最初使用股票代码的想法是正确的,你只是想阻止它。我只是在我的玩具示例中使用了sleep,我绝对不建议在代码中添加sleep@rek2使用@JimB下面的方法。我不是指实际的睡眠呼叫,你使用的是时间。After作为睡眠,并在应该使用间隔计时器的地方使用它。@rek2:你不应该使用时间。After作为睡眠,也不应该在这里使用睡眠。你最初使用股票代码的想法是正确的,你只是想阻止它。我只是在我的玩具示例中使用了sleep,我绝对不建议在代码中添加sleep@rek2使用@JimB下面的方法。我不是指实际的睡眠调用,你使用的是时间。之后作为睡眠,并在应该使用间隔计时器的地方使用它。这个编译吗?我在操场上看到了这一点:不能在ticker type*time.ticker范围内进行编译吗?我在操场上看到了这一点:不能超过ticker type*time.ticker的范围