现在咱们开始了解下如何进行群聊的一些主要功能,例如创建群、加入群、退出群等。
首先是创建群,废话不多说,直接上代码:
/**
* 创建群聊房间
* @param groupName 群名称
* @param users 创建群完成后添加的群成员
* @param nickName 群昵称
* @return
*/
public MultiUserChat createChatRoom(String groupName, List<User> users, String nickName) throws Exception {
//组装群聊jid,这里需要注意一下,群jid的格式就是 群名称@conference.openfire服务器名称
String jid = groupName + "@conference." + connection.getServiceName();
EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
MultiUserChat muc = getMultiUserChatManager().getMultiUserChat(groupJid);
muc.create(Resourcepart.from(nickName));
// 获得聊天室的配置表单
Form form = muc.getConfigurationForm();
// 根据原始表单创建一个要提交的新表单。
Form submitForm = form.createAnswerForm();
// 设置聊天室的新拥有者
List<String> owners = new ArrayList<>();
owners.add(AppInfo.user.getName()+ "@" + XmppUtils.getXmmpUtils().getConnection().getServiceName());
//这里的用户实体我要说一下,因为这是我这个项目的实体,实际上这里只需要知道用户的jid获者名称就可以了
if(users != null && !users.isEmpty()) {
for (int i = 0; i < users.size(); i++){ //添加群成员,用户jid格式和之前一样 用户名@openfire服务器名称
EntityBareJid userJid = JidCreate.entityBareFrom(users.get(i).getUsername() + "@" + XmppUtils.getXmmpUtils().getConnection().getServiceName());
owners.add(userJid + "");
}
}
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
//设置为公共房间
submitForm.setAnswer("muc#roomconfig_publicroom", true);
// 设置聊天室是持久聊天室,即将要被保存下来
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
// 房间仅对成员开放
submitForm.setAnswer("muc#roomconfig_membersonly", false);
// 允许占有者邀请其他人
submitForm.setAnswer("muc#roomconfig_allowinvites", true);
//进入不需要密码
submitForm.setAnswer("muc#roomconfig_passwordprotectedroom", false);
// 能够发现占有者真实 JID 的角色
// submitForm.setAnswer("muc#roomconfig_whois", "anyone");
// 登录房间对话
submitForm.setAnswer("muc#roomconfig_enablelogging", true);
// 仅允许注册的昵称登录
submitForm.setAnswer("x-muc#roomconfig_reservednick", false);
// 允许使用者修改昵称
submitForm.setAnswer("x-muc#roomconfig_canchangenick", true);
// 允许用户注册房间
submitForm.setAnswer("x-muc#roomconfig_registration", false);
// 发送已完成的表单(有默认值)到服务器来配置聊天室
muc.sendConfigurationForm(submitForm);
//添加群消息监听
muc.addMessageListener(new InGroupChatMessageListener(jid));
return muc;
}
这里要说明一下几个重点,首先是群账号格式,还有添加用户的格式,都不能弄错,否则会收不到信息的。其次就是一些相关群设置都注释了在上面,在最后,我们添加了个消息监听事件,监听器只需要实现MessageListener接口就可以监听群的所有消息
创建好群后,我们就开始发送群消息:
/**
* 发送群聊普通消息
* @param groupName
* @param body
*/
public void sendChatGroupMessage(String groupName, String body) throws Exception {
//拼凑jid
String jid = groupName + "@conference." + connection.getServiceName();
//创建jid实体
EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
//群管理对象
MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
//发送信息
multiUserChat.sendMessage(body);
}
我们想要发送群聊消息,都必须经过群管理对象MultiUserChatManager来创建群聊Chat才可以去发送消息
接下来就是其他用户如何主动加入群,代码如下:
/**
* 加入群聊会议室
* @param groupName
* @param nickName
* @return
* @throws Exception
*/
public MultiUserChat joinMultiUserChat(String groupName, String nickName) throws Exception {
//群jid
String jid = groupName + "@conference." + connection.getServiceName();
//jid实体创建
EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
//获取群管理对象
MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
//通过群管理对象获取该群房间对象
MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
MucEnterConfiguration.Builder builder = multiUserChat.getEnterConfigurationBuilder(Resourcepart.from(nickName));
//只获取最后99条历史记录
builder.requestMaxCharsHistory(99);
MucEnterConfiguration mucEnterConfiguration = builder.build();
//加入群
multiUserChat.join(mucEnterConfiguration);
return multiUserChat;
}
接下来就是退出群,代码如下:
/**
* 退出群聊
* @param groupName
* @throws XmppStringprepException
*/
public void quitRoom(String groupName) throws Exception {
String jid = groupName + "@conference." + connection.getServiceName();
EntityBareJid groupJid = JidCreate.entityBareFrom(jid);
MultiUserChatManager multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = multiUserChatManager.getMultiUserChat(groupJid);
//退出群
multiUserChat.leave();
}
以上就是基本的群操作,现在我来说说我还记得遇到的坑:
1:权限、权限、权限!因为如果你进群后,默认角色是普通成员,普通成员也就只有发送消息、接收消息的权限,如果在操作其他功能,如获取用户列表、踢人这些功能是会报没有权限的错误,所以这个需要给用户赋予管理员或者以上级别。
2:在进入群合退出群的时候,记得要注册或注销监听器,以免造成内存泄漏
由于这个项目已经结束了大半年,然后又因为工作原因,博主有很多地方也都不记得了。。。。。。
可以给大家看看博主之前做的简单的效果:
这一系列的文章就到这里吧,希望大家也可以多多包涵一些错误并指出!
---------------更新一下--------------
有小伙伴提的几个问题我先说一下,在这里小伙伴说得对,就是每次退出了账号登陆,再重新登录的时候确实是获取不了群的,那是因为在你退出登陆的时候,也会把你的群都退出了,在openfire里这个也不叫群,叫会议室,就是只有在线的时候才能加入,离线的话就会退出,openfire在这里做的就有点反人类了...
不过会议室如果在创建的时候设置了submitForm.setAnswer("muc#roomconfig_persistentroom", true);就会永久保存下来,所以也就是说房间是存在的,只是人员不在,在这里说说我们项目实现的思路:把群信息保存进用户本地数据库里面,如用户A创建了群,就会把群账号、群主以及群成员等一些信息保存到本地,等用户A上线了,就会去读取本地数据库里的群信息,在初始化的时候调用方法进入会议室并设置好消息监听。然后开始同步服务端的数据群数据,openfire在服务端会自动创建几个用于保存群数据的数据库表(具体哪几个我忘了...)
由于时间比较长,而且已经烂尾了的项目,所以很多细节也不记得了,谢谢大家的理解!