即時通信之客戶端篇StropheJs.

摘要

小編是個寫了幾年php的碼農, 接觸純Js的項目這也是頭一次,另外,IM的服務端是Java(tigase框架) ,爲了解決舊版本BOSH(長輪詢)即時消息不穩定問題,決定更換pc網頁版爲websockt連接, App用socket直連,特此更新服務端到8.0,更新安裝期間遇到了很多坑,再次記錄,熟練IM或者xmpp協議用法的不用繼續看了。javascript

怎麼添加帳戶,測試是否成功等工具方法見另外一篇php

傳送門

基礎語法

xmpp尋址和節,另外一篇基礎 應用層協議之xmpp基礎學習
xmpp主要是以xml格式傳輸數據,詳細請看xep協議,這裏用strophe的構建器,主要用到的以下:html

$iq,info query,主要用來查詢服務器信息,解析的最終結果是<iq></iq>。
$pres,解析的最終結果是<presence></presence>,上下線通知。
$msg, 解析的結果是<message></message>,同時能夠經過.up()和.c()構建xml父子級別元素。

執行流程

登錄認證

im.connect = new Strophe.Connection("ws://localhost:5290/xmpp-websocket/");
im.connect.connect('jid@localhost','pass',function(){
    console.info('this is login callback.');
});

這裏,服務端實際上是分爲兩步走,第一步是鏈接,鏈接成功後會返回狀態碼1,而後是登錄,登錄成功後返回狀態5,詳細的狀態碼參考源碼:
clipboard.png
關於密碼認證的問題,暫時採起plain方式,後續更新其餘方式,好比:sha1。java

單聊

  • 發送demo
var msg = $msg({
            to: receiver,
            from: 'jid@localhost',
            type: 'one',
            name: 'zeronlee',
            photo: 'image.png'
        }).c("body", null,msg);
        im.connect.send(msg.tree());
  • 查詢歸檔(歷史記錄漫遊)

查詢歸檔以前,首先是要確保歸檔(存庫)成功,服務端查看【傳送門】,自行處理,參見XEP-0136: Message Archivingnode

最簡單的demo:webpack

var iq = $iq({type: 'set'}).c('query', {xmlns: 'urn:xmpp:mam:1'});
    im.connect.sendIQ(iq, function(a){
        console.log('sent iq',a);

        $(a).find('item').each(function(){
            var jid = $(this).attr('jid'); // jid
            console.log('jid',jid);
        });
    });

成功後返回如下信息:git

<iq xmlns="jabber:client" to="im7857@localhost" id="d8a7cd10-16dd-43ae-ace2-20089713c920:sendIQ" type="result">
<fin xmlns="urn:xmpp:mam:1" complete="true">
<set xmlns="http://jabber.org/protocol/rsm">
  <first index="0">nAhOrNd/DNXBFtivwbm/vrN8I4GL2SLkc76eNmN0ruw=</first>
  <last>cnosUN6U9Md6o8TvLD42rB6jJnfPKF2DxkEBFmuK/IQ=</last>
  <count>14</count>
</set>
</fin>
</iq>

代表查出了14條歷史消息,查詢歸檔更多見XEP-0313: Message Archive Management,示例代碼見《插件使用方法》。github

羣聊

羣聊相對單聊要複雜的多,首先是入羣(這裏的羣沒有密碼),出席,發消息。web

  • 出席
var presence = $pres({from:'im7858@localhost',to:'6043@muc.localhost'}).c('x', {xmlns: 'http://jabber.org/protocol/muc'}).c('history', {maxstanzas: 0, maxchars:0, seconds:0});
    im.connect.send(presence, function(a){
        console.log('sent presence',a);
   
    });
  • 查詢羣開放功能信息
var presence = $iq({from:'im7858@localhost@muc.localhost'}).c('query', {xmlns: 'http://jabber.org/protocol/disco#items'});
im.connect.send(presence, function(a){
    console.log('sent presence',a);

});
  • 發消息同單聊

訂閱推送

內網穿透

插件使用方法

mam歸檔查詢demo編程

/* XEP-0313: Message Archive Management
 * Copyright (C) 2012 Kim Alvefur
 *
 * This file is MIT/X11 licensed. Please see the
 * LICENSE.txt file in the source package for more information.
 *
 * Modified by: Chris Tunbridge (github.com/Destreyf/)
 * Updated to support v0.3 of the XMPP XEP-0313 standard
 * http://xmpp.org/extensions/xep-0313.html
 *
 */

Strophe.addConnectionPlugin('mam', {
    _c: null,
    _p: [ 'with', 'start', 'end' ],
    init: function (conn) {
        this._c = conn;
        Strophe.addNamespace('MAM', 'urn:xmpp:mam:1');
    },
    query: function (jid, options) {
        var _p = this._p;
        var attr = {
            type:'set',
            from:jid
        };
        options = options || {};
        var mamAttr = {xmlns: Strophe.NS.MAM, with:jid};
        if (!!options.queryid) {
            mamAttr.queryid = options.queryid;
            delete options.queryid;
        }
        var iq = $iq(attr).c('query', mamAttr);

        // var i;
        // for (i = 0; i < this._p.length; i++) {
        //     var pn = _p[i];
        //     var p = options[pn];
        //     delete options[pn];
        //     if (!!p) {
        //         iq.c('field',{var:pn}).c('value').t(p).up().up();
        //     }
        // }
        // iq.up();
        //
        var onMessage = options.onMessage;
        delete options.onMessage;
        var onComplete = options.onComplete;
        delete options.onComplete;
        ////////////////////////////////////////////////
        // iq.cnode(new Strophe.RSM(options).toXML());

        var _c = this._c;
        var handler = _c.addHandler(onMessage, null, 'message', null);
        return this._c.sendIQ(iq, function (a) {
            console.log(a);
                _c.deleteHandler(handler);
                onComplete.apply(this, arguments);
            },
            function (err) {
                //error callBack function
                console.log("Error Response from server:", err);
            });
    }
});

插件必須是Strophe.addConnectionPlugin('mam', {init:function(){}})結構才得以成功加載,用webpack或者頁面加載進來以後自動實例化init,羣聊就是以插件形式使用,固然還能夠自定義其餘更高級的,具體參考《XMPP高級編程+使用JavaScript和jQuery》第三部分十四章。

栽過的坑

  • addHandlers轉handlers的時候回調函數丟失.

參考文獻

  • XMPP高級編程+使用JavaScript和jQuery
相關文章
相關標籤/搜索