redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
20.15k stars 2.37k forks source link

redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported #2539

Open cuipeiyu opened 1 year ago

cuipeiyu commented 1 year ago

When I try to subscribe messages using ssh, an error occurred. The messages has been confirmed to be able to be pushed correctly. How do i fix it?

Version: v9.0.3

Demo:

package main

import (
    "context"
    "log"
    "net"
    "time"

    "github.com/melbahja/goph"
    "github.com/redis/go-redis/v9"
    "golang.org/x/crypto/ssh"
)

func main() {
    var err error

    cfg := &goph.Config{
        User:     "root",
        Addr:     "<IP>",
        Port:     22,
        Timeout:  10 * time.Second,
        Callback: ssh.InsecureIgnoreHostKey(),
    }
    cfg.Auth, err = goph.Key("<key file>", "")
    if err != nil {
        panic(err)
    }

    tunnel, err := goph.NewConn(cfg)
    if err != nil {
        panic(err)
    }
    defer tunnel.Close()

    // test
    out, err := tunnel.Run("ls -al")
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("ssh test output:\n%s\n", string(out))

    rcfg := &redis.Options{
        Addr:         "127.0.0.1:6379",
        Password:     "", // no password set
        DB:           0,  // use default DB
        ReadTimeout:  -2,
        WriteTimeout: -2,
        Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
            return tunnel.Dial(network, addr)
        },
    }

    client := redis.NewClient(rcfg)
    defer client.Close()

    // test
    if err := client.Set(context.Background(), "abc", "123", time.Minute).Err(); err != nil {
        log.Fatalln("set \"abc\" failed", err.Error())
    }
    log.Println("set \"abc\" succeeded")

    go func() {
        channel := client.Subscribe(context.Background(), "test")
        c := channel.Channel()

        for {
            msg := <-c
            log.Println("new message: ", msg.Payload)
        }
    }()

    go func() {
        for {
            log.Println("publish message: ", "hello world")
            if err := client.Publish(context.Background(), "test", "hello world").Err(); err != nil {
                log.Fatalln("publish message error:", err.Error())
            }
            time.Sleep(time.Second)
        }
    }()

    select {}
}

Output:

2023/04/05 13:49:58 ssh test output:
total 40
drwx------  5 root root 4096 Apr  5 09:19 .
drwxr-xr-x 18 root root 4096 Apr  5 09:12 ..
-rw-r--r--  1 root root  571 Apr 11  2021 .bashrc
drwx------  3 root root 4096 Feb  8 13:34 .config
drwxr-xr-x  2 root root 4096 Feb  8 13:30 .pip
-rw-r--r--  1 root root  161 Jul  9  2019 .profile
-rw-r--r--  1 root root  206 Apr  5 09:12 .pydistutils.cfg
drwx------  2 root root 4096 Feb  8 21:31 .ssh
-rw-------  1 root root  815 Apr  5 09:19 .viminfo
-rw-r--r--  1 root root  215 Apr  5 09:13 .wget-hsts

2023/04/05 13:49:59 set "abc" succeeded
2023/04/05 13:49:59 publish message:  hello world
redis: 2023/04/05 13:49:59 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
redis: 2023/04/05 13:50:00 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
redis: 2023/04/05 13:50:00 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
2023/04/05 13:50:01 publish message:  hello world
redis: 2023/04/05 13:50:01 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
redis: 2023/04/05 13:50:01 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
2023/04/05 13:50:02 publish message:  hello world
redis: 2023/04/05 13:50:02 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
2023/04/05 13:50:03 publish message:  hello world
redis: 2023/04/05 13:50:03 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
redis: 2023/04/05 13:50:04 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
2023/04/05 13:50:04 publish message:  hello world
redis: 2023/04/05 13:50:05 pubsub.go:168: redis: discarding bad PubSub connection: ssh: tcpChan: deadline not supported
........
monkey92t commented 1 year ago

The pubsub module in go-redis doesn't support ssh-conn very well, you can consider using ReceiveTimeout. As for the <-chan message mode, it is currently not compatible with the ssh protocol.