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