如何在React中通过Converse Strophe获取在线用户列表及插件展示
通过Converse JS获取在线用户列表的方法
Converse JS基于Strophe.js实现,获取在线用户列表可以通过两种方式:利用Converse内置的Roster API,或者直接用Strophe发送XMPP请求处理在线状态。以下是具体实现方案:
一、利用Converse内置API(推荐)
Converse已经封装了联系人(Roster)管理功能,你可以直接通过内置方法获取在线用户:
- 监听联系人加载完成事件
在插件的initialize方法中,监听contactsFetched事件(当联系人列表首次加载或更新时触发),然后调用getOnlineContacts()获取在线用户:
export const moderationActions = () => { window.converse.plugins.add('moderation-actions', { dependencies: [], initialize: function () { const _converse = this._converse; // 监听联系人列表加载完成事件 _converse.api.listen.on('contactsFetched', () => { // 获取所有在线联系人 const onlineUsers = _converse.roster.getOnlineContacts(); // 在线用户列表会返回包含jid、name等属性的对象数组 console.log('在线用户列表:', onlineUsers); // React环境下,可以通过自定义事件将数据传递到组件 window.dispatchEvent(new CustomEvent('onlineUsersUpdated', { detail: onlineUsers })); }); // 监听联系人在线状态变化(可选) _converse.api.listen.on('contactPresenceChanged', (contact) => { console.log('联系人状态更新:', contact.jid, contact.presence); // 重新获取最新在线列表 const onlineUsers = _converse.roster.getOnlineContacts(); window.dispatchEvent(new CustomEvent('onlineUsersUpdated', { detail: onlineUsers })); }); }, }); };
- 在React组件中接收数据
在你的React组件里,监听自定义事件来更新组件状态:
import { useEffect, useState } from 'react'; function OnlineUsersList() { const [onlineUsers, setOnlineUsers] = useState([]); useEffect(() => { const handleUpdate = (e) => { setOnlineUsers(e.detail); }; window.addEventListener('onlineUsersUpdated', handleUpdate); return () => window.removeEventListener('onlineUsersUpdated', handleUpdate); }, []); return ( <div> <h3>在线用户</h3> <ul> {onlineUsers.map(user => ( <li key={user.jid}>{user.name || user.jid}</li> ))} </ul> </div> ); }
二、直接使用Strophe手动处理(进阶)
如果需要更底层的控制,可以用Strophe发送XMPP IQ请求获取Roster,并监听Presence消息来跟踪在线状态:
export const moderationActions = () => { window.converse.plugins.add('moderation-actions', { dependencies: [], initialize: function () { const _converse = this._converse; const Strophe = window.converse.env.Strophe; const connection = _converse.connection; // 存储在线用户的对象 const onlineUsers = new Map(); // 1. 请求获取完整联系人列表(Roster) const iq = $iq({ type: 'get' }).c('query', { xmlns: Strophe.NS.ROSTER }); connection.sendIQ(iq, (response) => { // 解析联系人列表 const contacts = response.querySelectorAll('item'); contacts.forEach(contact => { const jid = contact.getAttribute('jid'); onlineUsers.set(jid, { jid, name: contact.getAttribute('name') || jid }); }); }); // 2. 监听所有Presence消息,更新在线状态 connection.addHandler((presence) => { const from = presence.getAttribute('from'); const type = presence.getAttribute('type'); // 处理上线/可用状态 if (!type || type === 'available') { onlineUsers.set(from, { jid: from, name: from.split('@')[0] }); } // 处理下线/离开状态 else if (type === 'unavailable') { onlineUsers.delete(from); } // 通知React组件更新 window.dispatchEvent(new CustomEvent('onlineUsersUpdated', { detail: Array.from(onlineUsers.values()) })); return true; }, null, 'presence'); }, }); };
注意事项
- 确保Converse已正确初始化并完成登录,否则无法获取Roster和Presence数据
- 如果你需要获取MUC(多人聊天室)的在线用户,需要用
_converse.chatboxes.get(muc_jid).occupants来获取
内容的提问来源于stack exchange,提问作者Karim
相关产品推荐
相关产品推荐

