Publish 與 Subscribe 的對應機制,
常會用在需即時回應,
最常見的是即時聊天、對談的場合。
測試redis-cli裡Publish Subscribe功能
開兩個terminal,一邊執行訂閱chat1的頻道:
redis 127.0.0.1:6379> SUBSCRIBE chat1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "chat1"
3) (integer) 1
1) "message"
2) "chat1"
3) "broadcast to chat1"
另一邊做publish到chat1頻道,
redis 127.0.0.1:6379> PUBLISH chat1 "broadcast to chat1"
(integer) 1
redis 127.0.0.1:6379>
只要有訂閱chat1頻道,可即時收到此訊息。
psubscribe的功能
前面多個P是指 pattern 樣式相同者,
只要是符合其樣式的頻道之訊息,
就會收到該訊息:
redis 127.0.0.1:6379> PSUBSCRIBE news.*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.*"
3) (integer) 1
1) "pmessage"
2) "news.*"
3) "news.sports"
4) "OOO to chat1"
1) "pmessage"
2) "news.*"
3) "news.linux"
4) "OOO to linux"
redis 127.0.0.1:6379> PUBLISH news.sports "OOO to chat1"
(integer) 1
redis 127.0.0.1:6379> PUBLISH news.linux "OOO to linux"
(integer) 1
簡單的對談機制
編輯一個訂閱三個頻道的接收端:
require 'rubygems'
require 'redis'
require 'json'
$redis = Redis.new(:timeout => 0)
$redis.subscribe('i5.life', 'i5.tech', 'ithelp') do |on|
on.message do |channel, msg|
data = JSON.parse(msg)
puts "##{channel} - [#{data['user']}]: #{data['msg']}"
end
end
預計接收到JSON的格式,
再依其資料格式來畫出。
執行後收到的樣子是這樣:
$ ruby sub.rb
#i5.tech - [twtw]: helo
#i5.tech - [twtw]: 中文?
#i5.tech - [twtw]: 鐵人賽?
做一個可發佈訊息的publish端:
require 'rubygems'
require 'redis'
require 'json'
$redis = Redis.new
data = {"user" => ARGV[1]}
loop do
msg = STDIN.gets
$redis.publish ARGV[0], data.merge('msg' => msg.strip).to_json
end
透過cli指定頻道及發言的使用者名稱後,
鍵入的資料即發佈到各訂閱端。
$ ruby pub.rb i5.tech twtw
helo
中文?
鐵人賽?
而透過 MONITOR 指令,
可看到redis上發佈的動作。
$ redis-cli
redis 127.0.0.1:6379> MONITOR
OK
1350897192.371800 "MONITOR"
1350897213.011988 "publish" "i5.tech" "{\"user\":\"twtw\",\"msg\":\"\xe9\x90\xb5\xe4\xba\xba\xe8\xb3\xbd\xef\xbc\x9f\"}"