觀察者模式 | 以設計模式的視角解析mqtt協議



最近項目里用到一個基于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)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 本文翻譯自http://www.hivemq.com/blog/mqtt-essentials-part2-pub...
    qinwenbo閱讀 3,922評論 0 4
  • 最近項目需要做到網絡環境復雜 網絡環境差的情況下 實時刷新終端(凈化器)狀態,客戶端數據,相比較于htt...
    Mr_不靠譜_先森閱讀 2,236評論 0 4
  • 導語 翻譯自iot in five days 8.2 MQTT是什么?MQTT(formerly MQ Telem...
    happy1993閱讀 6,565評論 1 14
  • 1.原理: MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸協議...
    老友_閱讀 9,458評論 1 3
  • 念恩醒過來的時候,床上已經只有他自己了。臥室的門虛掩著,廚房荷包蛋的香味從門縫里溜進來,他可以聽到滋滋滋的油鍋聲。...
    凌素閱讀 420評論 0 2