Smack4.20实现群聊(4)

现在咱们开始了解下如何进行群聊的一些主要功能,例如创建群、加入群、退出群等。

首先是创建群,废话不多说,直接上代码:

/**
     * 创建群聊房间
     * @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在服务端会自动创建几个用于保存群数据的数据库表(具体哪几个我忘了...)

 

由于时间比较长,而且已经烂尾了的项目,所以很多细节也不记得了,谢谢大家的理解!

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值