美文网首页
基于xmpp.js搭建即时通讯客户端

基于xmpp.js搭建即时通讯客户端

作者: 詹小云 | 来源:发表于2018-10-12 16:14 被阅读0次

写在前面

//环境配置
UI库:VUE  v2.5.17
客户端:electron v2.0.10
NODE:8.9.3
platform: win64

前期分析


在搭建之前,我搜集了一下关于xmpp库的资料。比较热门的两个库是:xmpp.js 和 strophe.js。OK,那接下来我们来评估一下两者的差别(截止本日,即2018/10/08)。

类别 \ 名称 xmpp strophe
github☆ 1600 1091
issue 32(open) 280(closed) 19(open) 186(closed)
最新提交 1天前 6天前
npm下载量/week 400 1000
文档完善度 还行
官方demo 简单易懂 看到头疼
es6 支持 不支持

其实还有个最重要的功能点的比较,我没有写出来,是因为xmpp的文档实在是一言难尽。有很多参数和功能都需要自己进github里边查看,所以到现在我还在摸索,也就没办法比较两者。
两者光看上边的信息分析,一般在星星数和更新数不相上下的情况下,我会选择文档齐全的。毕竟没有写在文档上的功能就相当于不存在。然而,坑总是与你不期而遇。strophe.js的官方demo是以JQ来搭配的,所以我要自己稍微修改一下安装和引用方式。如下:

# install
npm install strophe.js --save

# require
let client = require('strophe.js')

但是这是一次失败的改造,当我想要创建一个client时,被告知获取不到 connection 这个方法。打印如下:

console.log(Strophe,Strophe.Connection)
log

如果非要用script引用方式的话,也不是不可以,在官网上把js文件下载下来,放到static文件夹中,然后在main.js中引用。但是这样就使得更新变得很麻烦,一旦习惯了npm,要退回script时代真的是接受唔到啊!所以,我决定考虑一下xmpp.js。

介绍xmpp.js


xmpp.js是让web也能用上即时通讯的一个库。关于xmpp协议以及xmpp.js这个库概念上的东西,网上相关博客已有许多,我也不多做描述,主要是记录使用感。

  1. 文档查看方式
    ok,既然他们更新文档,那我也更新一下文档查看方式。目前,他们的官方文档分了两种:GIitHub官网。按现在的进度来看,官网是旧版本的。按需求查看吧。
    友情提示:用yarn安装时,node>=10.0.0

搭建客户端


因为v0.3.0和v0.5.0的搭建我都试过了,所以就都写写。
新版跟旧版,最明显的功能差就是,新版自带keep-alive,而旧版则是6秒下线。当初为了维持心跳,可把我一个小新人折腾坏了。

新版v0.5.0
         //先定义常量
        const {client, xml, jid} = require('@xmpp/client')
        const user = 'zxy';
        const psw = 'password';

        //这真的是很重要的一句话!!!!因为node不支持自签证书的,所以如果当你连接的是自签证书的网,建议你赶紧加上
        process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

        //添加 domain的时候连接不上,为什么连不上?还不清楚
        const xmpp = client({
            service: 'xmpp://10.254.2.11:5222',
            // domain: '10.254.2.11',
            resource: 'PC-12334234hiasdhasgasd',
            username: user,
            password: psw,
        })

        //监听错误信息
        xmpp.on('error', err => {
            console.error('❌', err.toString())
        })

        //监听是否掉线
        xmpp.on('offline', () => {
            console.log('🛈', 'offline')
        })

        //监听是否上线
        xmpp.on('online', async address => {
            console.log('🗸', 'online as',address)

            // Sends a chat message to itself
            // 这是新版的官方文档写法,但是我这样写的时候无法获取到别人给我发的消息。
            // const message = xml(
            // 'message',
            // {type: 'chat', to: address},
            // xml('body', 'hello world')
            // )

            // 旧版官方的写法:旨在告诉服务器我已经上线了。发送了这句话后,我就可以收到服务器传来的消息。
            const presence = xml('presence', {}, 
                xml('show', {}, 'chat'),
                xml('status', {}, 'presence!'),
            )
            xmpp.send(presence)
        })

        //监听节点信息,不管是iq还是message,都是在这里监听到的。
        xmpp.on('stanza', stanza => {
            if (stanza.is('presence') && stanza.attrs.type === 'subscribe') {
                xmpp.send(
                    xml('presence', { to: stanza.attrs.from, type: 'subscribed' })
                );
            }

            // This is doing the echoing.
            if (stanza.is('message') && stanza.attrs.from !== client.jid) {
                console.log('⮈', stanza.toString())
                stanza.children.forEach(child => {
                    if (child.name === 'body') {
                        // do somethind 
                        // eg: put the message into your screen
                    }
                });
            }
        })

        // 监听状态
        xmpp.on('status', (status, value) => {
            console.log('status:', status, value ? value.toString() : '')
        })

        xmpp.start().catch(err=>{
            console.log(err)
        })

旧版v0.3.0

旧版大部分功能与新版是类似的,所以就不会每个功能点都注释一遍,只有特别要注意的地方才会写上。

      //aha,firstly we sholud import xmpp
      import {Client , xml} from 'xmpp.js'

      // 定义常量
      const client = new Client();
      const user = 'zxy';
      const psw = 'password';

      process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

      client.on('error', err => {
        console.error('❌', err.toString())
      })

      client.on('status', (status, value) => {
        // console.log('🛈', status, value ? value.toString() : '')
      })

      client.on('online', jid => {
        // console.log('🗸', 'online as', jid.toString())
        client.send(
          xml('presence', {}, 
            xml('show', {}, 'chat'),
            xml('status', {}, 'I say everything you do!'),
          )
        );
        
        // Send keepalive,这是我在issue上找到的写法,但是对我无效
        // client.Socket.prototype.setTimeout(0)
        // client.Socket.prototype.setKeepAlive(true, 10000)   
      })

      client.on('stanza', stanza => {
        // console.log('⮈', stanza.toJSON())
        if (stanza.is('presence') && stanza.attrs.type === 'subscribe') {
          client.send(
            xml('presence', { to: stanza.attrs.from, type: 'subscribed' })
          );
        }

        // 服务器发送ping过来时,要回应他以示存在
        if(stanza.is('iq')){
          client.send(
            xml('iq', { to: stanza.attrs.from, type: 'result', from: client.jid })
          );
        }

        // This is doing the echoing.
        if (stanza.is('message') && stanza.attrs.from !== client.jid) {
          // console.log('message',stanza.toJSON())
          // console.log('message');
          
          stanza.children.forEach(child => {
            if (child.name === 'body') {
              // do something you like
            }
          });
        }
      })

      client.start('xmpp://10.254.2.11:5222')
        .catch(err => console.error('start failed', err.message));
      // 验证链接
      client.handle('authenticate', authenticate => {
        return authenticate(user, psw)
      })
      // 添加资源
      client.handle('bind', bind => {
        return bind('PC-12334234hiasdhasgasd')
      })

ok,这样就搭建成功了,但是新版目前有个问题就是:在启动服务时,会报超时的错误,但是事实上,他已经链接上了。毕竟我是可以接受以及发送消息的。

相关文章

网友评论

      本文标题:基于xmpp.js搭建即时通讯客户端

      本文链接:https://www.haomeiwen.com/subject/rkupoftx.html