はじめに
RedisのGo言語向けクライアントライブラリRedigoの使い方を見ます。
あまり知られていないかもしれませんが、RedisにはPub/Sub(パブリッシュ/サブスクライブ)機能があります。この機能を使うと、例えばサーバ間のメッセージ通知のような1対多の通信を行うことができます。この記事ではパブリッシュ/サブスクライブの行い方を見ます。
環境
- OS: Windows 10
- Redis: win-3.2.100
- Go言語: 1.11
サブスクライブ
Redisでは、いわゆる「トピックベース」の通信ができます。受信側(サブスクライバー)は始めにトピック(チャネルと呼びます)を指定して購読を開始し、チャネルからの通信を待機します。
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")、購読チャネル数が得られます。
パブリッシュ
次は送信側(パブリッシャー)のコードです。
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でのパブリッシュ/サブスクライブの行い方を見ていきました。