0

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

Ling Guo
  • 592
  • 4
  • 12

1 Answers1

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
larsks
  • 277,717
  • 41
  • 399
  • 399