【问题标题】:How to write better Receive() in Golang for Redis(redigo) Pubsub?如何在 Golang 中为 Redis(redigo) Pubsub 编写更好的 Receive()?
【发布时间】:2015-10-17 12:20:39
【问题描述】:
psc := redis.PubSubConn{c}
psc.Subscribe("example")

func Receive() {
    for {
        switch v := psc.Receive().(type) {
        case redis.Message:
            fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
        case redis.Subscription:
            fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
        case error:
            return v
        }
    }
}

在上面的代码中(取自Redigo doc),如果连接丢失,所有订阅也会丢失。有什么更好的方法可以从丢失的连接中恢复并重新订阅。

【问题讨论】:

  • 如何创建一个redis.Pool,其Dial 函数也订阅相应的频道。
  • @tim-cooper 非常干净的方式。 +1

标签: go redis publish-subscribe redigo


【解决方案1】:

使用两个嵌套循环。外循环获取连接,设置订阅,然后调用内循环接收消息。内部循环一直执行,直到连接出现永久性错误。

for {
    // Get a connection from a pool
    c := pool.Get()
    psc := redis.PubSubConn{c}

    // Set up subscriptions
    psc.Subscribe("example"))

    // While not a permanent error on the connection.
    for c.Err() == nil {
        switch v := psc.Receive().(type) {
        case redis.Message:
            fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
        case redis.Subscription:
            fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
        case error:
            fmt.Printf(err)
        }
    }
    c.Close()
}

本示例使用 Redigo pool 获取连接。另一种方法是直接拨打连接:

 c, err := redis.Dial("tcp", serverAddress)

【讨论】:

  • Tim Cooper 在评论中的解决方案更简洁。拨号在重新连接期间负责订阅。谢谢+1
  • @aloksrivastava78 从拨号订阅可防止在应用程序中将池用于其他目的,将订阅代码移到远离接收代码的位置,并且根据 redigo 文档是不允许的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多