如何在Golang中更好地编写Redis(redigo) Pubsub的Receive()函数?

huangapple go评论81阅读模式
英文:

How to write better Receive() in Golang for Redis(redigo) Pubsub?

问题

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文档),如果连接丢失,所有的订阅也会丢失。有什么更好的方法可以从连接丢失中恢复并重新订阅。

英文:
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
        }
    }
}

In the above code(taken from Redigo doc), if connection is lost, all subscriptions are also lost. What will be better way to recover from lost connection and resubscribe.

答案1

得分: 9

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

for {
    // 从连接池获取连接
    c := pool.Get()
    psc := redis.PubSubConn{c}

    // 设置订阅
    psc.Subscribe("example")

    // 当连接没有永久错误时
    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 的 连接池 来获取连接。另一种方法是直接拨号连接:

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

Use two nested loops. The outer loop gets a connection, sets up the subscriptions and then invokes the inner loop to receive messages. The inner loop executes until there's a permanent error on the connection.

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()
}

This example uses a Redigo pool to get connections. An alternative is to dial a connection directly:

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

huangapple
  • 本文由 发表于 2015年10月17日 20:20:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/33186550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定