You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Strophe.js+Ejabberd通过XEP-0313获取聊天历史仅返回计数无内容求助

问题分析与解决方案

你的问题核心在于Strophe.js的sendIQ回调仅处理最终的IQ响应,而MAM的聊天历史消息是以独立的<message> stanza形式返回的,不会包含在最终的IQ结果里。你看到的<fin>只是服务器发送的查询完成通知,实际消息早在这之前就已经单独发送了。

修正步骤

  1. 注册临时消息监听器:在发送MAM查询前,先添加一个监听器来捕获服务器返回的MAM消息条目。
  2. 发送MAM查询IQ:保持原有的IQ请求结构,但调整后续处理逻辑。
  3. 处理消息与清理监听器:在监听器中解析每个MAM消息,收到最终的IQ完成通知后移除监听器。

修正后的代码示例

// 定义临时监听器,用于捕获MAM消息
const mamMessageHandler = function(msg) {
    // 检查是否是MAM的结果消息
    const result = msg.querySelector('result[xmlns="urn:xmpp:mam:2"]');
    if (!result) {
        return true; // 不是MAM消息,继续传递给其他监听器
    }

    // 提取原始消息内容
    const forwarded = result.querySelector('forwarded[xmlns="urn:xmpp:forward:0"]');
    if (forwarded) {
        const message = forwarded.querySelector('message');
        const body = Strophe.getText(message.querySelector('body'));
        const from = message.getAttribute('from');
        displayMessage(from, body);
    }

    return true;
};

// 添加监听器
connection.addHandler(mamMessageHandler, null, 'message', null, null, null);

// 构建MAM查询IQ(保持原有结构)
const iq = $iq({
    type: 'set',
    id: 'juliet1',
}).c('query', {
    xmlns: 'urn:xmpp:mam:2'
}).c('x', {
    xmlns: 'jabber:x:data',
    type: 'submit'
}).c('field', {
    var: 'FORM_TYPE',
    type: 'hidden'
}).c('value').t('urn:xmpp:mam:2').up().up().c('field', {
    var: 'with'
}).c('value').t(jid).up().tree();

// 发送IQ并处理完成通知
connection.sendIQ(iq, function(response) {
    // 查询完成,移除临时监听器
    connection.deleteHandler(mamMessageHandler);
    console.log('MAM查询完成,共返回', response.querySelector('count').textContent, '条消息');
}, function(error) {
    // 处理查询错误,同样移除监听器
    connection.deleteHandler(mamMessageHandler);
    console.error('MAM查询失败:', error);
});

关键说明

  • MAM的消息流:服务器收到MAM查询后,会先逐个发送包含<result>的<message>,最后发送包含<fin>的IQ响应表示查询结束。
  • 监听器的作用:addHandler注册的函数会捕获所有 incoming 的<message>,我们通过判断是否包含MAM命名空间的<result>来筛选目标消息。
  • Forwarded节点:MAM返回的原始消息会被包裹在<forwarded>节点中,需要解析这个节点才能拿到实际的聊天消息内容。

额外检查点

  • 确保你的jid变量是正确的完整JID(比如user@localhost/resource或者仅user@localhost,取决于你要查询的对话类型)。
  • 若需要分页获取大量历史消息,可以结合XEP-0059(Result Set Management)在查询中添加<set>节点,指定max、before或after参数。

内容的提问来源于stack exchange,提问作者speedy.user

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:10:29