You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 12:06:04