Redigoを使う(6) パブリッシュ/サブスクライブ


はじめに

RedisのGo言語向けクライアントライブラリRedigoの使い方を見ます。

あまり知られていないかもしれませんが、RedisにはPub/Sub(パブリッシュ/サブスクライブ)機能があります。この機能を使うと、例えばサーバ間のメッセージ通知のような1対多の通信を行うことができます。この記事ではパブリッシュ/サブスクライブの行い方を見ます。

環境

サブスクライブ

Redisでは、いわゆる「トピックベース」の通信ができます。受信側(サブスクライバー)は始めにトピック(チャネルと呼びます)を指定して購読を開始し、チャネルからの通信を待機します。

subscriber.go
package main

import (
    "fmt"

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

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    psc := redis.PubSubConn{Conn: conn}
    psc.Subscribe("channel_1", "channel_2", "channel_3")
    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:
            return
        }
    }
}

上記はサンプルをほぼそのまま持ってきたコードです。イディオム的にそのまま使えばよいと思います(実用的には切断された時に再接続を試す処理が必要と思います)。Subscribeで購読を開始するチャネルを並べて記し、Receiveでブロッキングでメッセージを待機します。

サブスクライブに成功するとチャネルはredis.Subscriptionを受け取ります(case節の2つ目)。このとき成功したチャネル名と通知の種類("subscribe")、購読チャネル数が得られます。

パブリッシュ

次は送信側(パブリッシャー)のコードです。

publisher.go
package main

import (
    "fmt"

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

func main() {
    // 接続
    conn, err := redis.Dial("tcp", "localhost:6379")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // パブリッシュ
    r, err := redis.Int(conn.Do("PUBLISH", "channel_1", "hello"))
    if err != nil {
        panic(err)
    }
    fmt.Println(r)
}

サブスクライバー側のコードを実行した状態で上のコードを実行すると、サブスクライバー側のターミナルにメッセージが表示されます。複数を起動していれば全てに同じ内容が表示されます。

パブリッシャー側のコードは比較的単純です。PUBLISHコマンドでチャネルとメッセージを指定して送信します。戻り値はメッセージが配信されたサブスクライバーの数になります。

おわりに

Redidoでのパブリッシュ/サブスクライブの行い方を見ていきました。

参考