搭建IM服務 so easy

如今不少網站、APP都經過IM服務來實現消息推送及數據即時同步功能,即時通信組件逐漸成爲產品的標配。目前國內有不少成熟穩定的第三方即時通信服務廠家,好比:融雲。使用這些專業的服務能夠提升開發效率並且服務穩定有保障。javascript

若是本身DIY或者須要在封閉的局域網內使用IM服務,該怎麼辦呢?下文就簡單介紹一下EasyPM曾經實踐過的自行搭建IM服務過程。html

數據同步方式

實現數據同步,有"推"、"拉" 兩種思路,具體有如下幾種方式:java

  1. 使用HTTP輪循方式
    • 說明:定時向HTTP服務端接口(Web Service API)獲取最新消息,可結合ajax技術實現頁面無刷新效果,這是主動拉取消息的機制。
    • 優勢:實現簡單、可控性強、部署成本低
    • 缺點:實時性差,增長服務端負載
  2. 使用XMPP協議
    • 說明:XMPP是基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線現場探測。它促進在服務器之間的準即時操做,其前身是Jabber,是一個開源形式組織產生的網絡即時通訊協議。XMPP目前被IETF國際標準組織完成了標準化工做。
    • 優勢:協議成熟、強大、可擴展性強、目前主要應用於衆多IM系統
    • 缺點:協議比較複雜、冗餘(基於XML)、費流量
  3. 使用MQTT協議
    • 說明:MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通信協議,該協議支持全部平臺,是輕量級的、基於代理的「發佈/訂閱」模式的消息傳輸協議
    • 優勢:MQTT協議簡潔、可擴展性強、流量開銷很小、網絡傳輸時間短
    • 缺點:還不夠成熟、實現較複雜

EasyPM做爲一個團隊協做應用,消息/數據推送功能是不可或缺的。由於MQTT比較輕量且網絡開銷小等特色,咱們選擇了支持MQTT協議的Apollo。git

Apollo是什麼?

Apollo是apache旗下的基金項目,它是以Apache ActiveMQ5.x爲基礎,採用全新的線程和消息調度架構從新實現的消息中間件,針對多核處理器進行了優化處理,它的速度更快、更可靠、更易於維護。apollo與ActiveQQ同樣支持多協議:STOMP、AMQP、MQTT、Openwire、 SSL、WebSockets,本文只介紹MQTT協議的使用。web

mqtt

下載Apollo

進入Apollo下載頁面 ,選擇下載合適的版本ajax

若是操做是系統是Windows Vista或更高版本,則須要安裝Microsoft Visual C++ 2010 Redistributable: 64位JVM 32位JVMapache

建立Apollo實例及服務

  1. 建立實例 進入E:\apache-apollo-1.7之下的bin目錄,打開cmd窗口,執行命令:apollo create D:\apollo_broker,命令執行成功後,在D盤下會有apollo_broker目錄,這即是apollo的服務實例,apollo之旅便從這裏開始。 在D:\apollo_broker下有個bin目錄,其中有兩個文件: apollo-broker.cmd是經過cmd命令啓動apollo服務的 apollo-broker-service.exe,是用於建立window服務的
  2. 命令行啓動服務 在D:\apollo_broker\bin目錄下打開cmd窗口,執行apollo-broker run命令來啓動apollo服務, 啓動成功能夠在瀏覽器中查看運行狀況,訪問地址爲 http://127.0.0.1:61680 , 默認用戶名/密碼:admin/password
  3. 建立windows服務 找到cmd.exe文件,點擊鼠標右鍵,以管理員身份運行,輸入建立windows服務命令,以下圖:

建立成功後,在windows服務中會有一個apollo_broker服務,設置隨系統自動啓動windows

MQTT協議的應用

MQTT協議有衆多客戶端實現,相關客戶端請參考apollo官方文檔 本文采用eclipse的paho客戶端實現瀏覽器

####web端接收消息介紹 將 javascript客戶端項目下載下來,並在其項目根目錄下執行mvn命令,進行編譯,生成target目錄,其下生成mqttws31.js、mqttws31-min.js兩個js文件,將其拷貝到本身項目相關目錄下,並在頁面中引用,便可實現javascript客戶端的消息訂閱和發佈,demo代碼以下:服務器

var client = new Paho.MQTT.Client(location.hostname, 61623,"/", "clientId"); 
/* 61623是ws鏈接的默認端口,能夠在apollo中間件中進行配置
(關於apollo的配置請參考:
 http://activemq.apache.org/apollo/documentation/user-manual.html
) */
// set callback handlers 
client.onConnectionLost = onConnectionLost; 
client.onMessageArrived = onMessageArrived; 
// connect the client 
client.connect({userName:'admin',password:'password',onSuccess:onConnect}); 
// called when the client connects 
function onConnect() { // 鏈接成功後的處理 
		// Once a connection has been made, make a subscription and send a message. 
		console.log("onConnect"); 
		client.subscribe("/topic/event"); // 訂閱消息的主題 
		var message = new Paho.MQTT.Message("Hello,this is a test"); 
		message.destinationName = "/topic/event"; 
		client.send(message); // 發送消息 
} 
// called when the client loses its connection 
function onConnectionLost(responseObject) { // 鏈接丟失後的處理 
		if (responseObject.errorCode !== 0) { 
				console.log("onConnectionLost:"+responseObject.errorMessage); 
		} 
} 
// called when a message arrives 
function onMessageArrived(message) { // 消息接收成功後的處理 
		console.log("onMessageArrived:"+message.payloadString); 
}

####服務端消息發送介紹 paho java客戶端目前只支持J2SE和安卓,提供源碼下載和maven庫。 咱們採用maven庫,其地址以下: Official Releases Nightly Snapshots maven dependency配置:

<dependency> 
		<groupId>org.eclipse.paho</groupId> 
		<artifactId>org.eclipse.paho.client.mqttv3</artifactId> 
		<version>1.0.1</version> 
</dependency>

java實現代碼:

String topic        = "MQTT Examples"; 
        String content      = "Message from MqttPublishSample";
        int qos             = 2;
        String broker       = "tcp://127.0.0.1:61613";
        String clientId     = "JavaSample";
        MemoryPersistence persistence = new MemoryPersistence();
        try {
            MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
            MqttConnectOptions connOpts = new MqttConnectOptions();
            connOpts.setCleanSession(true);
            System.out.println("Connecting to broker: "+broker);
            sampleClient.connect(connOpts);
            System.out.println("Connected");
            System.out.println("Publishing message: "+content);
            MqttMessage message = new MqttMessage(content.getBytes());
            message.setQos(qos);
            sampleClient.publish(topic, message);
            System.out.println("Message published");
            sampleClient.disconnect();
            System.out.println("Disconnected");
            System.exit(0);
        } catch(MqttException me) {
            System.out.println("reason "+me.getReasonCode());
            System.out.println("msg "+me.getMessage());
            System.out.println("loc "+me.getLocalizedMessage());
            System.out.println("cause "+me.getCause());
            System.out.println("excep "+me);
            me.printStackTrace();
        }

小結

至此,MQTT協議已部署完畢,java端能夠發佈消息,而javascript端則能夠訂閱並接收到java端發佈的信息。在搭建的過程當中,能夠參考如下資源:

  1. MQTT
  2. ActiveMQ5
  3. Apollo官方文檔
  4. eclipse paho
相關文章
相關標籤/搜索