最近項目里用到一個基于mqtt協議的代理服務器Mosquitto,我們需要將其適配到openwrt上并作簡單的系統用戶驗證,折騰了一陣, 算是完成了。
但重點不在這, 重點在于, 我對mqtt基于publish / subscribe模式的通信方式, 產生了興趣。
雖然之前對這種模式的應用也有一些了解,比如EventBus的事件監聽機制,比如XMPP消息傳輸機制。但是并沒有正經地去研究過它的實現,現在我用python實現一個小demo,完成基于publish/subscribe模式的消息通信,祭奠這段時間對Mosquitto的奉獻~~~
定義
我們先來了解下什么叫基于publish / subscribe模式的通信方式,話先不多說,上圖么么噠:
發布者: 發布消息給broker服務器上的某個主題, 他不關心有多少訂閱者
訂閱者: 從broker那訂閱主題消息, 他不關心誰是發布者
broker服務器: 負責推送發布者的消息給訂閱者; 負責維護訂閱者列表
以上, 便是三者各自負責的任務, 而mosquitto就是通過以下三個命令來完成上述消息通信過程:
mosquitto -c /etc/mosquitto/mosquitto.conf
mosquitto_sub -t "test" // -t ==> topic
mosquitto_pub -t "test" -m "testaddress" // -m ==> message
通過這三個命令, 我們以黑盒的方式YY一下, 它是如何實現的咧? 下圖是我用觀察者模式YY的一種實現方式哈!
接著就是把圖用python代碼化:
Topic
class Topic:
def __init__(self, topic_name):
self.subscribers = []
self.name = topic_name
def attach(self, subscriber):
if subscriber not in self.subscribers:
self.subscribers.append(subscriber)
def deattach(self, subscriber):
if subscriber in self.subscribers:
self.subscribers.remove(subscriber)
def notify(self, msg):
for s in self.subscribers:
s.update(msg)
Subscriber
class Subscriber:
def __init__(self, sub_name):
self.name = sub_name
def update(self, recv_msg):
print "訂閱者" + self.name + "收到消息:\\\\\\\\t" + recv_msg
Publisher
class Publisher:
def __init__(self, pub_name):
self.name = pub_name
def publish(self, pub_msg, topic):
print "發布者" + self.name + "發布消息:\\\\\\\\t" + pub_msg + "\\\\\\\\n"
self.topic = topic
self.topic.notify(pub_msg)
Main
if __name__ == '__main__':
coder_Jameson = Subscriber("Jameson")
coder_Tom = Subscriber("Tom")
coder_Peter = Subscriber("Peter")
boss = Publisher("BOSS")
platform_topic = Topic("platform")
platform_topic.attach(coder_Jameson)
platform_topic.attach(coder_Tom)
platform_topic.attach(coder_Peter)
print "\\\\\\\\n---------------------\\\\\\\\n"
boss.publish("寫一個微信小程序", platform_topic)
print "\\\\\\\\n---------------------\\\\\\\\n"
boss.publish("寫一個RN APP", platform_topic)
print "\\\\\\\\n---------------------\\\\\\\\n"
boss.publish("寫一個nodejs后臺服務", platform_topic)
print "\\\\\\\\n---------------------\\\\\\\\n"
運行結果
總結
最后的最后, 我們來總結下利用觀察者模式實現的方法, 有什么優劣:
*優點: * 正如前文所說, 觀察者模式解耦了觀察者與發布者之間的關系, 二者互不關心
*缺點: * 如果Topic被過多人訂閱的話, 那么發布者發布的消息通知就會推送的比較慢,復雜度O(N)