Go语言使用Redis PubSub时如何正确接收发布的消息?
问题核心原因
你的代码执行顺序不符合Redis PubSub的工作规则:
- Redis PubSub不会缓存历史消息,只有发布消息时已经完成订阅的客户端才能收到对应消息
- 现有代码先执行了
PUBLISH发送test message,之后才调用Subscribe订阅example频道,消息发送时还没有完成订阅,自然收不到目标内容,只能拿到订阅成功的回调通知。
修正方案
调整执行顺序,先完成订阅再发布消息,同时建议发布和订阅使用独立的Redis连接(连接进入订阅模式后仅能执行PubSub相关命令,无法再执行普通操作,拆分连接更符合规范)。
修正后代码示例:
package main import ( "fmt" "log" "time" "github.com/gomodule/redigo/redis" ) func main() { fmt.Println("Start redis test.") // 订阅端单独使用一个连接 subConn, err := redis.Dial("tcp", "localhost:6379") if err != nil { log.Fatal(err) } defer subConn.Close() psc := redis.PubSubConn{Conn: subConn} if err := psc.Subscribe("example"); err != nil { log.Fatal(err) } // 订阅逻辑放到goroutine先启动 go func() { 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: fmt.Println(v) return } } }() // 短暂等待确保订阅完成,测试场景可用,生产环境建议用channel信号通知更优雅 time.Sleep(100 * time.Millisecond) // 发布端使用单独的连接 pubConn, err := redis.Dial("tcp", "localhost:6379") if err != nil { log.Fatal(err) } defer pubConn.Close() // 订阅完成后再发布消息即可正常接收 _, err = pubConn.Do("PUBLISH", "example", "test message") if err != nil { log.Println("publish error:", err) } // 保持进程运行一段时间方便查看输出 time.Sleep(1 * time.Second) }
运行后输出结果如下:
example: subscribe 1 example: message: test message
内容的提问来源于stack exchange,提问作者Ling Guo
相关产品推荐
相关产品推荐

