写在前面
//环境配置
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)
如果非要用script引用方式的话,也不是不可以,在官网上把js文件下载下来,放到static文件夹中,然后在main.js中引用。但是这样就使得更新变得很麻烦,一旦习惯了npm,要退回script时代真的是接受唔到啊!所以,我决定考虑一下xmpp.js。
介绍xmpp.js
xmpp.js是让web也能用上即时通讯的一个库。关于xmpp协议以及xmpp.js这个库概念上的东西,网上相关博客已有许多,我也不多做描述,主要是记录使用感。
- 文档查看方式
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,这样就搭建成功了,但是新版目前有个问题就是:在启动服务时,会报超时的错误,但是事实上,他已经链接上了。毕竟我是可以接受以及发送消息的。