Openfire smack开发之聊天室

2014/09/01

继续上一章smack的讲述,聊天室的操作,聊天室也是openfire提供的一种形式,类似qq的讨论组,并非群,可以多人加入进来进行群聊。

1.创建聊天室

public boolean createChatRoom(String roomName, String subject) {
    boolean result = false;
    try {
        MultiUserChat muc = new MultiUserChat(connectManager.getConnection(), roomName + "@conference." + connectManager.getDomain());
        muc.create(connectManager.getNode());
        Form form = muc.getConfigurationForm();
        Form submitForm = form.createAnswerForm();
        for (Iterator fields = form.getFields(); fields.hasNext();) {
            FormField field = (FormField) fields.next();
            if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
                submitForm.setDefaultAnswer(field.getVariable());
            }
        }
        // submitForm.setAnswer("muc#roomconfig_roomdesc", "wwh2222");
        List list = new ArrayList();
        list.add("20");
        submitForm.setAnswer("muc#roomconfig_maxusers", list);
        submitForm.setAnswer("muc#roomconfig_persistentroom", true);
        submitForm.setAnswer("muc#roomconfig_membersonly", false);
        submitForm.setAnswer("muc#roomconfig_allowinvites", true);
        submitForm.setAnswer("muc#roomconfig_enablelogging", true);
        submitForm.setAnswer("x-muc#roomconfig_reservednick", true);
        submitForm.setAnswer("x-muc#roomconfig_canchangenick", false);
        submitForm.setAnswer("x-muc#roomconfig_registration", false);
        muc.sendConfigurationForm(submitForm);
        muc.changeSubject(subject);
        result = true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

创建聊天室,主要就是在创建的时候根据需求对聊天室的一些属性进行设置

房间名称 text-single muc#roomconfig_roomname
描述 text-single muc#roomconfig_roomdesc
允许占有者更改主题 boolean muc#roomconfig_changesubject
最大房间占有者人数 list-single muc#roomconfig_maxusers
其 Presence 是 Broadcast 的角色 list-multi muc#roomconfig_presencebroadcast
列出目录中的房间 boolean muc#roomconfig_publicroom
房间是持久的 boolean muc#roomconfig_persistentroom
房间是适度的 boolean muc#roomconfig_moderatedroom
房间仅对成员开放 boolean muc#roomconfig_membersonly
允许占有者邀请其他人 boolean muc#roomconfig_allowinvites
需要密码才能进入房间 boolean muc#roomconfig_passwordprotectedroom
密码 text-private muc#roomconfig_roomsecret
能够发现占有者真实 JID 的角色 list-single muc#roomconfig_whois
登录房间对话 boolean muc#roomconfig_enablelogging
仅允许注册的昵称登录 boolean x-muc#roomconfig_reservednick
允许使用者修改昵称 boolean x-muc#roomconfig_canchangenick
允许用户注册房间 boolean x-muc#roomconfig_registration
房间管理员 jid-multi muc#roomconfig_roomadmins
房间拥有者 jid-multi muc#roomconfig_roomowners

消息包:

<presence id="5ryxs-4" to="testroom@conference.wenwh-pc/10110">
    <x xmlns="http://jabber.org/protocol/muc"></x>
</presence>

<iq id="5ryxs-5" to="testroom@conference.wenwh-pc" type="get">
    <query xmlns="http://jabber.org/protocol/muc#owner"></query>
</iq>

<iq id="5ryxs-6" to="testroom@conference.wenwh-pc" type="set">
    <query xmlns="http://jabber.org/protocol/muc#owner">
        <x xmlns="jabber:x:data" type="submit">
            <field var="FORM_TYPE" type="hidden">
                <value>http://jabber.org/protocol/muc#roomconfig</value>
            </field>
            <field var="muc#roomconfig_persistentroom" type="boolean">
                <value>1</value>
            </field>
            <field var="muc#roomconfig_membersonly" type="boolean">
                <value>0</value>
            </field>
            <field var="muc#roomconfig_allowinvites" type="boolean">
                <value>1</value>
            </field>
            <field var="muc#roomconfig_enablelogging" type="boolean">
                <value>1</value>
            </field>
            <field var="x-muc#roomconfig_reservednick" type="boolean">
                <value>1</value>
            </field>
            <field var="x-muc#roomconfig_canchangenick" type="boolean">
                <value>0</value>
            </field>
            <field var="x-muc#roomconfig_registration" type="boolean">
                <value>0</value>
            </field>
        </x>
    </query>
</iq>

2.加入聊天室

public boolean joinChatRoom(String roomName) {
    boolean result = false;
    try {
        MultiUserChat muc = new MultiUserChat(connectManager.getConnection(), roomName + "@conference." + connectManager.getDomain());
        // 添加消息监听
        muc.addMessageListener(new UcGroupChatManagerListener(this));
        // 添加其他聊天室人员状态变化监听
        muc.addParticipantStatusListener(new UcParticipantStatusListener(this, roomName));
        // 添加直接在聊天室的状态变化监听
        muc.addUserStatusListener(new UcUserStatusListener(this, roomName));
        // 添加邀请被拒绝的监听
        muc.addInvitationRejectionListener(new UcInvitationRejectionListener(this, roomName));
        muc.addPresenceInterceptor(new UcPresenceInterceptor());
        // 设置历史消息数量
        DiscussionHistory history = new DiscussionHistory();
        history.setMaxChars(0);
        muc.join(connectManager.getNode(), null, history, SmackConfiguration.getPacketReplyTimeout());
        // muc.grantOwnership("10110@kfas1/Spark 2.6.3");//对聊天室一些权限的授予,与删除
        // muc.grantAdmin("10110@kfas1/Spark 2.6.3");
        // muc.grantMembership("10110@kfas1/Spark 2.6.3");
        // muc.grantModerator("10110");
        // muc.grantVoice("10110");
        // muc.revokeVoice("10110");
        muc.revokeAdmin("10110@kfas1/Spark 2.6.3");
        mucMap.put(roomName, muc);
        result = true;
    } catch (XMPPException e) {
        log.error("加入聊天室异常", e);
    }
    return result;
}

消息包:

<presence id="CC26U-4" to="testroom@conference.wenwh-pc/10110">
    <x xmlns="http://jabber.org/protocol/muc">
        <history maxchars="0" />
    </x>
</presence>

3.离开聊天室

public boolean departChatRoom(String roomName) {
    boolean result = false;
    MultiUserChat muc = mucMap.get(roomName);
    if (muc != null) {
        muc.leave();
        mucMap.remove(roomName);
        result = true;
    }
    return result;
} 

消息包:

<presence id="fmmBY-5" to="testroom@conference.wenwh-pc/10110" type="unavailable"></presence>

4.邀请加入聊天室

public boolean inviteChatRoom(String roomName, String toJid, String reason) {
    boolean result = false;
    MultiUserChat muc = mucMap.get(roomName);
    if (muc != null) {
        muc.invite(toJid, reason);
        result = true;
    }
    return result;
}

消息包:

<message id="34B0W-5" to="testroom@conference.wenwh-pc/10110">
    <x xmlns="http://jabber.org/protocol/muc#user">
        <invite to="10111@wenwh-pc">
            <reason>一起聊天</reason>
        </invite>
    </x>
</message>

5.拒绝加入聊天室

public void rejectInvite(String room, String inviter, String reason) {
    MultiUserChat.decline(connectManager.getConnection(), room, inviter, reason);
}

消息包:

<message from="testroom@conference.wenwh-pc" to="10110@wenwh-pc">
    <x xmlns="http://jabber.org/protocol/muc#user">
        <decline from="10111@wenwh-pc">
            <reason>No thank you</reason>
        </decline>
    </x>
</message>

6.查询聊天室人员名字

public List<String> findMulitUser(String roomName) {
    MultiUserChat muc = mucMap.get(roomName);
    List<String> listUser = new ArrayList<String>();
    if (muc != null) {
        Iterator<String> it = muc.getOccupants();
        while (it.hasNext()) {
            String name = StringUtils.parseResource(it.next());
            listUser.add(name);
        }
    }
    return listUser;
}

7.发送聊天室消息

public boolean sendChatMessage(String roomName, String content) {
    boolean result = false;
    try {
        MultiUserChat muc = mucMap.get(roomName);
        if (muc != null) {
            Message message = new Message();
            message.setBody(content);
            message.setTo(muc.getRoom());
            message.setType(Message.Type.groupchat);
            message.setSubject(MSG_SUBJECT);
            muc.sendMessage(message);
            result = true;
        }
    } catch (XMPPException e) {
        log.error("发送消息异常", e);
    }
    return result;
}

消息包:

<message id="f6tkr-5" to="testroom@conference.wenwh-pc" type="groupchat">
    <body>测试聊天室消息</body>
</message>

8.聊天室中角色与关系

实例在上面加入聊天室已经给出

角色:
    moderator:主持人 (可以进行踢人,禁止发言等授权)
    participant:参与者 (可以发言)
    visitor:访客(不能发言)
    none:无
关系:
    owner:拥有者
    admin:管理员
    member:会员
    outcast:被禁止加入的
    none:无

在smcak里面的授权:(角色会随着关系变化,反之不会)

授予拥有者,管理员,会员,发言,主持人
被授予拥有,管理的时候,角色自动变成:主持人
被授予会员的时候,角色变成:参与者
被授予主持人,关系不会变化
被禁止发言:角色变成访客

聊天室的主要操作都在这里讲述,其实可能还有一些其他的,大家可以多看看smack的源码就会发现更多的隐藏协议。

目录

博客搜索