Strophe.js串連XMPP伺服器Openfire、Tigase實現Web私聊、群聊(MUC),xmppopenfire

來源:互聯網
上載者:User

Strophe.js串連XMPP伺服器Openfire、Tigase實現Web私聊、群聊(MUC),xmppopenfire

XMPP(Extensible Messaging and Presence Protocol)是一種網路即時通訊協議,它基於XML,具有很強的擴充性,被廣泛使用在即時通訊軟體、網路遊戲交談、Web聊天及Web訊息推送、行動裝置的訊息推送等情境,例如Google的GTalk、《英雄聯盟LOL》遊戲交談模組。

由於在Web瀏覽器上的JavaScript不能直接處理TCP協議,所以XMPP伺服器通常會提供BOSH(Bidirectional-streams Over Synchronous HTTP)介面,通過HTTP長輪訓(long-polling)可以實現Web瀏覽器即時聊天。Strophe.js是一個通過BOSH串連Web瀏覽器和XMPP伺服器的工具庫。

XMPP協議簡介:

XMPP伺服器和用戶端之間,是通過XML節(XML Stanza)來進行通訊。其中有三種非常重要的XML Stanza類型:<message>、<presence>、<iq>。

<message>:

聊天訊息的發送和接收就是通過message節來實現。例如xxg1@host發送一條資訊"你好"給xxg2@host,xxg1@host用戶端會將下面的這段XML發送到XMPP伺服器,伺服器再推送給xxg2@host用戶端。其中<message>的from屬性是寄件者,to屬性是接收者,<body>子項目的內容就是聊天資訊。

<message from="xxg1@host" to="xxg2@host" type="chat">    <body>你好</body></message>

<presence>:

可用於表明使用者的狀態,例如使用者狀態改變成“Do not disturb”(“請勿打擾”),會向伺服器發送:

<presence from="xxg@host">    <status>Do not disturb</status>    <priority>0</priority>    <show>dnd</show></presence>
<iq>:

iq即Info/Query,採用“要求-回應”機制,類似於HTTP的機制。下面的例子是用戶端通過<iq>請求擷取連絡人,XMPP伺服器將結果返回:

用戶端請求擷取連絡人:

<iq from='xxg@host' id='bv1bs71f' type='get'>    <query xmlns='jabber:iq:roster'/></iq>
伺服器結果返回:

<iq to='xxg@host' id='bv1bs71f' type='result'>    <query xmlns='jabber:iq:roster'>        <item jid='xxg2@host'/>        <item jid='xxg3@host'/>    </query></iq>

搭建XMPP伺服器:

在實現Web瀏覽器聊天之前,首先要搭建一個XMPP伺服器。例如Openfire、Tigase、Ejabberd是常用的XMPP伺服器。其中Openfire、Tigase是基於Java實現,Ejabberd是Erlang實現。雖然實現的語言不同,但是都遵循XMPP協議,所以使用其中任意一個XMPP伺服器即可。

下面以Openfire和Tigase為例。

Openfire可以自動化搭建很方便,本文不再介紹。Tigase的搭建可以參考我的另一篇博文:Linux搭建XMPP伺服器Tigase(Spark用戶端測試)。

XMPP伺服器通常會實現BOSH擴充,下面是Openfire和Tigase的BOSH預設URL:

Openfire:http://host:7070/http-bind
Tigase:http://host:5280

在使用Strophe.js的時候,需要使用對應的HTTP地址才能串連上XMPP伺服器。

如果使用Opnefire,還需要在管理後台配置一下:


Strophe.js:

下載:http://strophe.im/strophejs/

實現Web私聊:

私聊比較簡單,聊天資訊是通過上面介紹的<message>來進行傳遞交換。例如接收到一條別人發來的聊天資訊,即接收一個<message>元素,發送給別人一條聊天資訊,即發送一個<message>元素。

HTML:

<!DOCTYPE html><html><head><script src='http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js'></script><script src='http://cdn.bootcss.com/strophe.js/1.1.3/strophe.min.js'></script><script src='test.js'></script></head><body>JID:<input type="text" id="input-jid"><br>密碼:<input type="password" id="input-pwd"><br><button id="btn-login">登入</button><div id="msg" style="height: 400px; width: 400px; overflow: scroll;"></div>連絡人JID:<input type="text" id="input-contacts"><br>訊息:<br><textarea id="input-msg" cols="30" rows="4"></textarea><br><button id="btn-send">發送</button></body></html>
JavaScript(test.js):

// XMPP伺服器BOSH地址var BOSH_SERVICE = 'http://host:5280';// XMPP串連var connection = null;// 目前狀態是否串連var connected = false;// 當前登入的JIDvar jid = "";// 串連狀態改變的事件function onConnect(status) {console.log(status)    if (status == Strophe.Status.CONNFAIL) {alert("串連失敗!");    } else if (status == Strophe.Status.AUTHFAIL) {alert("登入失敗!");    } else if (status == Strophe.Status.DISCONNECTED) {alert("串連斷開!");connected = false;    } else if (status == Strophe.Status.CONNECTED) {alert("串連成功,可以開始聊天了!");connected = true;// 當接收到<message>節,調用onMessage回呼函數connection.addHandler(onMessage, null, 'message', null, null, null);// 首先要發送一個<presence>給伺服器(initial presence)connection.send($pres().tree());    }}// 接收到<message>function onMessage(msg) {// 解析出<message>的from、type屬性,以及body子項目    var from = msg.getAttribute('from');    var type = msg.getAttribute('type');    var elems = msg.getElementsByTagName('body');    if (type == "chat" && elems.length > 0) {var body = elems[0];$("#msg").append(from + ":<br>" + Strophe.getText(body) + "<br>")    }    return true;}$(document).ready(function() {// 通過BOSH串連XMPP伺服器    $('#btn-login').click(function() {if(!connected) {connection = new Strophe.Connection(BOSH_SERVICE);connection.connect($("#input-jid").val(), $("#input-pwd").val(), onConnect);jid = $("#input-jid").val();}    });// 發送訊息$("#btn-send").click(function() {if(connected) {if($("#input-contacts").val() == '') {alert("請輸入連絡人!");return;}// 建立一個<message>元素並發送var msg = $msg({to: $("#input-contacts").val(), from: jid, type: 'chat'}).c("body", null, $("#input-msg").val());connection.send(msg.tree());$("#msg").append(jid + ":<br>" + $("#input-msg").val() + "<br>");$("#input-msg").val('');} else {alert("請先登入!");}});});
修改JavaScript代碼中的BOSH_SERVICE,用瀏覽器開啟HTML檔案,登入後即可聊天:


實現Web群聊:

XMPP群聊通過XMPP協議的MUC(Multi-User Chat)擴充實現。

Openfire預設支援MUC,但是Tigase伺服器預設不支援MUC,需要在init.properties檔案中加入以下粗體部分的配置項:

config-type=--gen-config-def
--admins=admin@host
--virt-hosts = host
--debug=server
--user-db=mysql
--user-db-uri = jdbc:mysql://localhost:3306/tigasedb?user=root&password=xxx
--comp-name-1 = muc
--comp-class-1 = tigase.muc.MUCComponent
--external = muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:accept

建立房間:

建立房間實際上可以寫在代碼中,但是本文為了方便,就使用XMPP用戶端Spark或者其他工具來建立。

首先使用Spark任意登入一個使用者,是Spark建立房間的步驟:



如果使用的是Tigase,預設建立的房間是加鎖的,別的使用者無法進入,需要對房間解鎖。Spark進入房間後,點擊下面的設定按鈕,然後不用更改任何設定,直接更新即可解鎖房間(雖然沒有修改任何配置,但是更新時會發送一個<iq>給伺服器,這個<iq>解鎖了房間,參考http://xmpp.org/extensions/xep-0045.html#createroom-instant):


另外,如果使用Openfire可以直接使用管理後台來建立:


加入房間:

房間建立好了之後,就有有對應的房間JID:


加入房間可以通過發送一個<presence>來實現(實際上如果房間不存在下面的這條<presence>也會建立房間,但是建立的房間預設加鎖,還需要發送一條<iq>解鎖,所以本文就直接用Spark建立房間):

<presence from='xxg@host' to='xxgroom@muc.host/xxg'>    <x xmlns='http://jabber.org/protocol/muc'/></presence>
屬性to='xxgroom@muc.host/xxg'中,xxgroom@muc.host表示房間JID,xxg表示在房間的暱稱。

聊天:

和私聊一樣,群聊也是通過<message>來實現,不同的是<message>的type屬性,私聊是"chat",而群聊是"groupchat",另外,to屬性即為房間JID,這樣一條聊天訊息就會發送給房間中的所有人。

<message from='xxg@host' to='myroom@muc.host' type='groupchat'>  <body>大家好!</body></message>
實現:

HTML:

<!DOCTYPE html><html><head><script src='http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js'></script><script src='http://cdn.bootcss.com/strophe.js/1.1.3/strophe.min.js'></script><script src='test2.js'></script></head><body>JID:<input type="text" id="input-jid"><br>密碼:<input type="password" id="input-pwd"><br><button id="btn-login">登入</button><div id="msg" style="height: 400px; width: 400px; overflow: scroll;"></div><br>訊息:<br><textarea id="input-msg" cols="30" rows="4"></textarea><br><button id="btn-send">發送</button></body></html>
JavaScript(test2.js):

// XMPP伺服器BOSH地址var BOSH_SERVICE = 'http://host:5280';// 房間JIDvar ROOM_JID = 'xxgroom@muc.host';// XMPP串連var connection = null;// 目前狀態是否串連var connected = false;// 當前登入的JIDvar jid = "";// 串連狀態改變的事件function onConnect(status) {    if (status == Strophe.Status.CONNFAIL) {alert("串連失敗!");    } else if (status == Strophe.Status.AUTHFAIL) {alert("登入失敗!");    } else if (status == Strophe.Status.DISCONNECTED) {alert("串連斷開!");connected = false;    } else if (status == Strophe.Status.CONNECTED) {alert("串連成功,可以開始聊天了!");connected = true;// 當接收到<message>節,調用onMessage回呼函數connection.addHandler(onMessage, null, 'message', null, null, null);// 首先要發送一個<presence>給伺服器(initial presence)connection.send($pres().tree());// 發送<presence>元素,加入房間connection.send($pres({from: jid,to: ROOM_JID + "/" + jid.substring(0,jid.indexOf("@"))}).c('x',{xmlns: 'http://jabber.org/protocol/muc'}).tree());    }}// 接收到<message>function onMessage(msg) {console.log(msg);// 解析出<message>的from、type屬性,以及body子項目    var from = msg.getAttribute('from');    var type = msg.getAttribute('type');    var elems = msg.getElementsByTagName('body');    if (type == "groupchat" && elems.length > 0) {var body = elems[0];$("#msg").append(from.substring(from.indexOf('/') + 1) + ":<br>" + Strophe.getText(body) + "<br>")    }    return true;}$(document).ready(function() {// 通過BOSH串連XMPP伺服器    $('#btn-login').click(function() {if(!connected) {connection = new Strophe.Connection(BOSH_SERVICE);connection.connect($("#input-jid").val(), $("#input-pwd").val(), onConnect);jid = $("#input-jid").val();}    });// 發送訊息$("#btn-send").click(function() {if(connected) {// 建立一個<message>元素並發送var msg = $msg({to: ROOM_JID, from: jid, type: 'groupchat'}).c("body", null, $("#input-msg").val());connection.send(msg.tree());$("#input-msg").val('');} else {alert("請先登入!");}});});

建立好房間,修改JavaScript代碼中的BOSH_SERVICE和ROOM_JID,用瀏覽器開啟HTML檔案,登入後即可群聊:


另外,Strophe.js還有一個專門的MUC外掛程式,有興趣的同學可以自己研究下:https://github.com/strophe/strophejs-plugins/tree/master/muc。



作者:叉叉哥   轉載請註明出處:http://blog.csdn.net/xiao__gui/article/details/42642573




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.