How to receive Redis publish message in Go

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

How to receive Redis publish message in Go

问题

我正在尝试在Go中使用Redis PubSub来传递/发布消息并在订阅期间检索它。

我已经成功设置了代码中的发布和订阅/ PubSub部分。下面是我的代码。我期望在订阅期间检索到的(字符串)消息是test message。但是,我的代码输出的是通道、类型和计数,并没有显示预期的消息(test message)。

**在使用Redis发布/订阅在Go中发布后,如何获取预期的消息(test message)?**我觉得我很接近了,但可能有一点小问题。我对Redis非常陌生。感谢您的帮助。

以下是我的代码:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gomodule/redigo/redis"
)

func main() {
	fmt.Println("开始Redis测试。")

	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		log.Println(err)
	} else {
		log.Println("redis.Dial没有错误。")
	}
	// defer c.Close()

	/// 发布者。
	c.Do("PUBLISH", "example", "test message")
	/// 结束

	/// 订阅者。
	psc := redis.PubSubConn{Conn: c}
	psc.Subscribe("example")
	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			fmt.Printf("%s: 消息: %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)
		}
	}
	/// 结束

}

以下是我的输出:
example: subscribe 1

英文:

I am trying to use Redis PubSub in Go to be able pass / publish a message and retrieve it during subscription.

I have been able to set the publish and subscribe / PubSub parts of the code properly. Below is my code. The (string) message that I expect to retrieve during subscription is test message. But, the output of my code gives channel, kind and count and does not show the intended message (test message).

How can I get the intended message (test message) after Publish using Redis publish / subscribe in Go? I feel that I am close, but I may be missing a small thing here. I am very new to Redis. Thanks for your help.

Following is my code:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gomodule/redigo/redis"
)

func main() {
	fmt.Println("Start redis test.")

	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		log.Println(err)
	} else {
		log.Println("No error during redis.Dial.")
	}
	// defer c.Close()



	/// Publisher.
	c.Do("PUBLISH", "example", "test message")
	/// End here

	/// Subscriber.
	psc := redis.PubSubConn{Conn: c}
	psc.Subscribe("example")
	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)
		}
	}
	/// End here

}

Following is my output:
example: subscribe 1

答案1

得分: 1

我相信你的代码是没有问题的;问题在于你在订阅激活之前就发布了一条消息。例如,尝试一下这个代码,它将你的发布者放入一个 goroutine 中,每秒发布一条消息:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gomodule/redigo/redis"
)

func main() {
	fmt.Println("开始测试 Redis。")

	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		log.Println(err)
	} else {
		log.Println("redis.Dial 没有错误。")
	}
	// defer c.Close()

	/// 发布者。
	go func() {
		c, err := redis.Dial("tcp", "localhost:6379")
		if err != nil {
			panic(err)
		}

		count := 0
		for {
			c.Do("PUBLISH", "example",
				fmt.Sprintf("测试消息 %d", count))
			count++
			time.Sleep(1 * time.Second)
		}
	}()
	/// 结束

	/// 订阅者。
	psc := redis.PubSubConn{Conn: c}
	psc.Subscribe("example")

	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			fmt.Printf("%s: 消息: %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)
		}

		time.Sleep(1)
	}
	/// 结束

}

运行这个代码,你会看到你的订阅者每秒接收一条消息,产生如下输出:

开始测试 Redis。
2021/08/18 19:01:29 redis.Dial 没有错误。
example: subscribe 1
example: 消息: 测试消息 0
example: 消息: 测试消息 1
example: 消息: 测试消息 2
example: 消息: 测试消息 3
example: 消息: 测试消息 4
example: 消息: 测试消息 5
英文:

I believe your code is just fine; the problem is that you are publishing a message before your subscription is active. For example, try this, which puts your publisher into a goroutine that publishes a message once per second:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/gomodule/redigo/redis"
)

func main() {
	fmt.Println("Start redis test.")

	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		log.Println(err)
	} else {
		log.Println("No error during redis.Dial.")
	}
	// defer c.Close()

	/// Publisher.
	go func() {
		c, err := redis.Dial("tcp", "localhost:6379")
		if err != nil {
			panic(err)
		}

		count := 0
		for {
			c.Do("PUBLISH", "example",
				fmt.Sprintf("test message %d", count))
			count++
			time.Sleep(1 * time.Second)
		}
	}()
	/// End here

	/// Subscriber.
	psc := redis.PubSubConn{Conn: c}
	psc.Subscribe("example")

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

		time.Sleep(1)
	}
	/// End here

}

Run this and you'll see that your subscriber receives a message once a
second, producing output like:

Start redis test.
2021/08/18 19:01:29 No error during redis.Dial.
example: subscribe 1
example: message: test message 0
example: message: test message 1
example: message: test message 2
example: message: test message 3
example: message: test message 4
example: message: test message 5

huangapple
  • 本文由 发表于 2021年8月19日 05:57:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/68839793.html
匿名

发表评论

匿名网友

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

确定