1. 程式人生 > >使用ActiveMQ+MQTT實現Android點對點訊息通知

使用ActiveMQ+MQTT實現Android點對點訊息通知

使用ActiveMQ+MQTT實現Android點對點訊息通知

[email protected]

2013-12-20

實現點對點訊息通知的關鍵問題

ActiveMQ使用MQTT協議,加上android上的paho包,即可簡單實現訊息通知功能,但是mqtt協議只支援topic,而且不能用selector,使得點對點的訊息投遞變成問題。

有兩個解決思路:

1、每個clientId,建一個topic...這個辦法對解決訊息點對點投遞非常有效,但是有兩個大問題:

  • 隨著使用者數增多,topic數量增多,對管理性要求增大,對記憶體的管理也有問題。
  • 訊息廣播操作也變得非常麻煩,只能一個個的傳送了。

2、另一個思路,就是在訊息廣播的基礎上,進行點對點控制,實現某些特徵的訊息投遞到指定的訂閱者。

這個的實現比較簡單,而且沒有上面方案的大問題。程式碼稍微改下即可:https://github.com/apache/activemq/pull/5/files

其實就只添加了一個新的類: ClientIdFilterDispatchPolicy

可以git clone所在版本原始碼,然後加上這個類,mvn package以後使用。

更新到5.15.0-SNAPSHOT版本

使用說明

本修改實現mqtt協議使用單個topic,來做訊息廣播和點對點的投遞。

1、將本資料夾下的activemq-broker-5.9.0.jar、activemq-spring-5.9.0.jar換掉apache-activemq-5.9.0\lib下的jar。
2、參考本資料夾下activemq.xml,在topic上配置
 <dispatchPolicy>
                    <clientIdFilterDispatchPolicy />
                  </dispatchPolicy>
3、對於此配置下的所有名稱以.PTP結尾的佇列,
   如果要投遞訊息的properties裡包含PTP_CLIENTID,則系統只會將此訊息發給clientId為此值的訂閱者;如果當前沒有此clientId的訂閱者,訊息不會被任何人接收到。
   如果投遞訊息的properties裡不包含PTP_CLIENTID,則訊息廣播給所有的訂閱者。 跟正常訊息投遞一致。

其中字尾.PTP和鍵值PTP_CLIENTID,是可以配置的:
  <dispatchPolicy>
                    <clientIdFilterDispatchPolicy ptpSuffix="" ptpClientId="clientId"/>
                  </dispatchPolicy>
如上配置,使得此policy下的所有topic都起作用,且訊息的properties裡獲取clientId的key變成clientId。

訊息釋出者,如果要對所有人廣播訊息,直接傳送訊息即可。
            如果要對指定的訊息訂閱者發訊息,請在訊息裡設定接收者的clientId:

               message.setStringProperty(PTP_CLIENTID, clientId);則此訊息只有指定的訂閱者可以拿到。

簡單測試

兩臺android裝置使用MQTT協議訂閱到ActiveMQ的同一個topic,clientId分別為mqtt-1001和mqtt1002;

寫程式碼發兩條訊息,設定訊息屬性中PTP_CLIENTID分別為mqtt-1001和mqtt1002;

兩個裝置分別接收到自己的訊息通知,相互之間沒有影響。還可以測試下如果訊息沒有PTP_CLIENTID,兩個都能收到。