英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论