即时通讯之客户端篇StropheJs.

2019-07-12 admin

摘要

小编是个写了几年php的码农, 接触纯Js的项目这也是头一次,另外,IM的服务端是Java(tigase框架) ,为了解决旧版本BOSH(长轮询)即时消息不稳定问题,决定更换pc网页版为websockt链接, App用socket直连,特此更新服务端到8.0,更新安装期间遇到了不少坑,再次记录,熟练IM或者xmpp协议用法的不用继续看了。

怎么添加账户,测试是否成功等工具方法见另一篇

传送门

基础语法

xmpp寻址和节,另一篇基础 [应用层协议之xmpp基础学习](https://segmentfault.com/a/1190000019319742)
xmpp主要是以xml格式传输数据,详细请看xep协议,这里用strophe的构建器,主要用到的如下:
$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 关于ssl认证的问题,暂时采取plain方式,后续更新其他方式,比如:sha1。

单聊

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 Archiving

最简单的demo:

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);
        });
    });

成功后返回以下信息:

<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,示例代码见《插件使用方法》。

群聊

群聊相对单聊要复杂的多,首先是入群(这里的群没有密码),出席,发消息。

   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

[转载]原文链接:https://segmentfault.com/a/1190000019746485

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-69578.html

文章标题:即时通讯之客户端篇StropheJs.

相关文章
bootstrap table之通用方法( 时间控件,导出,动态下拉框, 表单验证 ,选中与获取信息)代码分享
1.bootstrap-table 单击单行选中 $(&#x27;#gzrwTable&#x27;).on(&#x27;click-row.bs.table&#x27;, function(e, row, $element) { $(&#x...
2017-02-17
JS教程之基础
javascript教程之什么是 JavaScript? JavaScript 被设计用来向 HTML 页面添加交互行为。JavaScript 是一种脚本语言(脚本语言是一种轻量级的编程语言)。JavaScript 由数行可执行计算机代码组...
2015-11-12
DOM之通俗易懂讲解
DOM 是所有前端开发每天打交道的东西,但是随着 jQuery 等库的出现,大大简化了 DOM 操作,导致大家慢慢的 “遗忘” 了它的本来面貌。不过,要想深入学习前端知识,对 DOM 的了解是不可或缺的,所以本文力图系统的讲解下 DOM 的...
2016-01-13
Ajax教程之Ajax介绍
Ajax 由 HTML、JavaScript™ 技术、DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家,他演示了这些技术如何协同工作 —— 从总体概述...
2015-11-12
Vue.js原理分析之observer模块详解
介绍 observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。 **注意:**本文是针对Vue@2.1.8进行分析 observer模块在Vue项目中的代码位置是src/c...
2017-03-16
数据格式之战:JSON vs XML
在比较JSON和XML之前,我们先来上一堂关于数据格式的简要历史(更准确的说,是关于XML的始祖): 早在1970年,IBM开发了一种叫Generalized Markup Language的标记语言,简称GML,它主要是为脚本语言定义的一...
2016-01-13
JavaScript深入之类数组对象与
类数组对象 所谓的类数组对象: 拥有一个 length 属性和若干索引属性的对象 举个例子: var array = [&#x27;name&#x27;, &#x27;age&#x27;, &#x27;sex&#x27;]; var ...
2017-05-27
javascript数据结构与算法之检索算法
查找数据有2种方式,顺序查找和二分查找。顺序查找适用于元素随机排列的列表。二分查找适用于元素已排序的列表。二分查找效率更高,但是必须是已经排好序的列表元素集合。 一:顺序查找 顺序查找是从列表的第一个元素开始对列表元素逐个进行判断,直到找到...
2017-03-22
HTML5之WebSocket入门3 -通信模型socket.io
socket.io为什么会诞生呢?请看下面文字说明。 为什么需要socket.io? node.js提供了高效的服务端运行环境,但是由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服...
2017-03-29
文字垂直滚动之javascript代码
在大型的网站新闻公告和友情链接等领域经常有这种文字或图片垂直滚动的效果,下面就介绍一下文字垂直滚动的javascript代码。 javascript代码如下: &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;h...
2017-03-27
回到顶部