gpt4 book ai didi

node.js - 使用 Node 处理 XMPP 存在

转载 作者:搜寻专家 更新时间:2023-10-31 23:49:12 24 4
gpt4 key购买 nike

我正在使用 node-xmpp 模块连接到 XMPP 服务器并加入群聊。到目前为止,连接到服务器、设置状态、加入房间和读出消息都可以。但我也想收到房间的用户列表。

XMPP 协议(protocol)要求在客户端进入房间时发送出席信息节 (http://xmpp.org/extensions/xep-0045.html#enter-pres)。但是我现在如何在 Node 中解析它?

我的代码目前看起来像这样:

var xmpp = require('node-xmpp');

// Create the XMPP Client
var cl = new xmpp.Client({
jid: jid,
password: password,
reconnect: true
});

// Do things when online
cl.on('online', function() {
util.log("We're online!");

// Set client's presence
cl.send(new xmpp.Element('presence', { type: 'available' }).c('show').t('chat'));
cl.send(new xmpp.Element('presence', { to: room_jid+'/'+room_nick }).c('x', { xmlns: 'http://jabber.org/protocol/muc' }).c('history', {seconds: 1}));

// Send keepalive
setInterval(function() {
cl.send(' ');
}, 30000);




cl.on('stanza', function(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}

// ignore everything that isn't a room message
if (!stanza.is('message') || !stanza.attrs.type == 'chat') {
return;
}

var body = stanza.getChild('body');
// message without body is probably a topic change
if (!body) {
return;
}

// Extract username
var from, room, _ref;
_ref = stanza.attrs.from.split('/'), room = _ref[0], from = _ref[1];
var message = body.getText();

// Log topics and messages to the console
if(!from) {
util.log('Topic: ' + message);
} else {
util.log('[' + from + ']: ' + message);
}
});
});

我已经尝试使用

if(stanza.is('presence')) {}

在 cl.on('stanza') 部分,但它不起作用。

最佳答案

更新:我现在正在描述一种不需要客户端发送请求的新方法。

背景:当客户端加入群聊时,服务器会返回状态节,其中包含有关加入群聊的用户的信息。

cl.on('stanza', function(stanza) {
// always log error stanzas
if (stanza.attrs.type == 'error') {
util.log('[error] ' + stanza);
return;
}

if(stanza.is('presence')){
// We are only interested in stanzas with <x> in the payload or it will throw some errors
if(stanza.getChild('x') !== undefined) {
// Deciding what to do based on the xmlns attribute
var _presXmlns = stanza.getChild('x').attrs.xmlns;

switch(_presXmlns) {
// If someone is joining or leaving
case 'http://jabber.org/protocol/muc#user':
// Get the role of joiner/leaver
_presRole = stanza.getChild('x').getChild('item').attrs.role;
// Get the JID of joiner/leaver
_presJID = stanza.getChild('x').getChild('item').attrs.jid;
// Get the nick of joiner/leaver
_presNick = stanza.attrs.from.split('/')[1];


// If it's not none, this user must be joining or changing his nick
if(_presRole !== 'none') {

// We are now handling the data of joinging / nick changing users. I recommend to use an in-memory store like 'dirty' [https://github.com/felixge/node-dirty] to store information of the users currentliy in the group chat.


} else {

// We are now handling the data of leaving users

}
break;
}

return;
}

return;
}

旧方法

我之前介绍了一种方法,如何查询当前群聊中的服务器。通过维护存储所有用户流量(加入、离开、更改昵称)的商店,不再需要这样做。但是,您仍然可以使用它来确保数据是一致的,例如存在节未正确传递给客户端等问题。这就是它仍然在下面描述的原因:

要请求包含连接到房间的用户的列表,您需要执行以下操作:

首先向服务器发送请求,请求用户列表:

cl.send(new xmpp.Element('iq', {from: jid, to: room_jid, type: 'get' }).c('query', { xmlns: 'http://jabber.org/protocol/disco#items' }));

然后监听 iq-stanzas,解析它们并用数据填充一个数组:

// Catching the requested user list
if(stanza.is('iq')){
// Fetching usernames from return data (data structure: http://xmpp.org/extensions/xep-0045.html#example-12)
var _items = stanza.getChild('query').getChildren('item');
var users = new Array();
for(var i = 0; i<_items.length; i++) {
// We are building an object here to add more data later
users[i] = new Object();
users[i]['name'] = _items[i].attrs.name;
}
console.log(util.inspect(users, {depth: null, colors: true}));
return;
}

这将为您提供一个用户列表。要请求唯一的 JID,您必须探查每个用户。为了使列表保持最新,您应该在用户离开时删除用户,并在他们加入时添加 + probe。

关于node.js - 使用 Node 处理 XMPP 存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17136432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com