【问题标题】:How to run a heartbeat function如何运行心跳功能
【发布时间】:2020-07-02 05:30:43
【问题描述】:

我看到了大量关于如何定期运行函数的问题。 问题?他们都锁定程序无法继续运行。

我需要什么? 我有一个 websocket,我有一个 for {},它一直在读取 msg,现在每 10 秒我需要运行一次对 heartbeat 函数的调用,而不会中断程序或停止阅读聊天。 我正在考虑使用一些方法,但使用渠道似乎都不干净/不错,但我认为更有经验的人可能对此有更好更简单的方法。

我正在使用类似的东西,但它永远不会到达函数的末尾以返回程序继续运行所需的内容。

timerCh := time.Tick(time.Duration(10) * time.Second)
  for range timerCh {
    go Heartbeat(ws)
}

return ws

我正在寻找一种能够每 10 秒调用一次 Heartbeat 的方法:

  1. 每次读取传入的 websocket 连接时都会重复调用它
  2. 不锁定程序。

一些上下文, 这是一个桥接聊天,所以我打开一个 websocket,继续阅读这个,只有在聊天消息时才发送到另一个聊天,同时我需要发送一个心跳而不锁定这个。 我现在有什么? 现在一切正常,但大约 30 秒后我的 websocket 关闭:

2020/07/01 20:59:09 Error read: websocket: close 1000 (normal)

【问题讨论】:

  • 为什么不把for循环放到goroutine中呢?
  • 从 websocket 读取的那个?因为它会连续进行Hearbeat(ws),我不希望这样,每10秒左右一次。如果我添加一个 timer.Tick 然后停止主 goroutine...
  • 这不是您使用自动收报机的原因吗,它只运行一次,每 10 秒运行一次?你也应该有一些方法来取消它(另外你不应该使用time.Tick,因为正如文档所述,你不能关闭它)
  • 嗯,也许这就是问题所在,我是新手,你能给我一个不会锁定我程序其余部分的例子吗?谢谢

标签: linux go websocket gorilla heartbeat


【解决方案1】:

编辑:选择@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 秒后终止。

【讨论】:

  • @rek2:你不应该使用time.After 作为睡眠,你也不应该在这里使用睡眠。您最初使用股票行情的想法是正确的,您只是希望能够阻止它。
  • 我只是在我的玩具示例中使用sleep,我绝不建议在您的代码中添加sleep。 @rek2 采用以下 @JimB 的方法。
  • 我不是指 实际 睡眠呼叫,您使用 time.After 作为睡眠,并在您应该使用间隔计时器的地方使用它。跨度>
【解决方案2】:

您希望能够关闭自动收报机,因此不要使用time.Tick,而是使用time.NewTicker。

如果你把整个for循环和ticker一起移动到一个goroutine中,它不会阻塞主goroutine。

go func() {
    ticker := time.NewTicker(10 * time.Second)
    defer ticker.Stop()
    for range ticker.C {
        Heartbeat(ws)
        // return on error or cancellation
    }
}()

【讨论】:

  • 这可以编译吗?我在操场上看到这个:cannot range over ticker (type *time.Ticker)
  • Heartbeat 通常只要程序运行就运行。所以不需要停止Tick,因为不需要GC。对于 Heartbeat 用例,Tick 应该没问题。见stackoverflow.com/questions/38856959/…
猜你喜欢
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
相关资源
最近更新 更多