• XMPP系列(六)---创建群组


    最近公司项目需要,要做一个自己的IMSDK,顺便先把之前没有记录的群聊功能记录一下。
    先上资料,查看XMPP群聊相关的资料,可以去这里看协议:XEP-0045

    创建群组

    XMPP 框架里有一个类XMPPRoom,利用这个类可以很容易的创建一个新的群组。

    1.创建群组的JID。

    群组的JID与用户的JID有一些区别。
    用户的JID规则是<userId@domain>
    群组的JID规则是<roomId@subdomain.domain/nick>
    而群组的subdomain 是需要提前在服务器端设置好的。

    1.1创建群组的服务

    如何创建群组服务呢?
    openfire 后台---> 分组聊天--->分组聊天设置中可以看到创建新的服务按钮。不知道的看下图:
    创建群组服务

    1.2 创建群组JID

    怎么写群组的JID呢?
    举个例子,如果我们要创建一个叫做abc 的群组,而我们的群组服务subdomain是group,而domain 是im.joker.cn,那么这个群组的JID就是abc@group.im.joker.cn

    JID 很重要,如果服务地址写错了,那么创建群组就没反应。
    另外 服务地址,必须是域名,不能是IP,否则也没反应。

    至于roomId的规则,这可以看你们的需求咯,比如我这里就是用时间,示例代码:

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyyMMddHHmmss"];
    NSString *currentTime = [formatter stringFromDate:[NSDate date]];
    NSString *roomId = [NSString stringWithFormat:@"%@@group.im.joker.cn/%@",currentTime,[JKXMPPTool sharedInstance].xmppStream.myJID.bare];
    
    XMPPJID *roomJID = [XMPPJID jidWithString:roomId];

    2.设置群组的存储策略

    // 如果不需要使用自带的CoreData存储,则可以使用这个。
    //    XMPPRoomMemoryStorage *xmppRoomStorage = [[XMPPRoomMemoryStorage alloc] init];
    
    // 如果使用自带的CoreData存储,可以自己创建一个继承自XMPPCoreDataStorage,并且实现了XMPPRoomStorage协议的类
    // XMPPRoomHybridStorage在类注释中,写了这只是一个实现的示例,不太建议直接使用这个,我这里为了图演示方便,就先用XMPPRoomHybridStorage吧。
    XMPPRoomHybridStorage *xmppRoomStorage = [XMPPRoomHybridStorage sharedInstance];
    XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:xmppRoomStorage jid:roomJID dispatchQueue:dispatch_get_main_queue()];

    3.激活XMPPRoom

    XMPPRoom继承自XMPPModule ,所以它也是需要使用XMPPStream来激活,并且也需要设置代理。

    [xmppRoom activate:[JKXMPPTool sharedInstance].xmppStream];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];

    4.加入群组

    这一步只有一行代码,但是却有两种不同的情况。

    [xmppRoom joinRoomUsingNickname:@"haley" history:nil password:nil];

    执行这一步时,如果房间已经存在,则是加入房间的操作。
    而如果房间不存在,则会先创建房间,然后再加入房间。

    5.设置群组的信息

    设置群组的参数,是创建群组成功,并加入群组成功后的代理方法中。
    XEP-0045中创建保留房间的章节下面有一个例子:
    例子 147. 例子 149.,里面有比较全的可以配置群组(房间)的参数。具体的可以配置的参数也可以在创建群成功后调用XMPPRoom{- fetchConfigurationForm}方法,去查看。

    参数 类型 说明
    muc#roomconfig_roomname text-single 群名称
    muc#roomconfig_roomdesc text-single 群的简短描述
    muc#roomconfig_changesubject boolean 是否允许群成员更改房间的主题
    muc#roomconfig_allowinvites boolean 是否允许邀请其他人进群
    muc#roomconfig_maxusers list-single 群成员的最大数量
    muc#roomconfig_presencebroadcast list-multi 我也不知道干啥的
    muc#roomconfig_publicroom boolean 群是否是公共的(在获取自己的群列表时,会获取到自己加入的群和公共的群)
    muc#roomconfig_persistentroom boolean 群是否是永久的
    muc#roomconfig_moderatedroom boolean 房间是适度的(我猜测是标识临时群)
    muc#roomconfig_membersonly boolean 是否只对群成员开放
    muc#roomconfig_passwordprotectedroom boolean 是否为群设置了密码,如果设置了密码,需要填写密码才能加群
    muc#roomconfig_roomsecret text-private 群密码
    muc#roomconfig_whois list-single 谁可以看到成员Jid
    muc#roomconfig_roomadmins jid-multi 设置哪些人为管理员
    muc#roomconfig_roomowners jid-multi 设置哪些人为群拥有者(不知道干啥的)
    x-muc#roomconfig_canchangenick boolean 是否允许群成员修改自己的群昵称
    x-muc#roomconfig_registration boolean 是否允许用户注册到房间

    下面是设置的示例代码:

    - (void)configNewRoom:(XMPPRoom *)xmppRoom
    {
        NSXMLElement *x = [NSXMLElement elementWithName:@"x"xmlns:@"jabber:x:data"];
        NSXMLElement *p = [NSXMLElement elementWithName:@"field" ];
        [p addAttributeWithName:@"var"stringValue:@"muc#roomconfig_persistentroom"];//永久房间
        [p addChild:[NSXMLElement elementWithName:@"value"stringValue:@"1"]];
        [x addChild:p];
    
        p = [NSXMLElement elementWithName:@"field" ];
        [p addAttributeWithName:@"var"stringValue:@"muc#roomconfig_maxusers"];//最大用户
        [p addChild:[NSXMLElement elementWithName:@"value"stringValue:@"10000"]];
        [x addChild:p];
    
        p = [NSXMLElement elementWithName:@"field" ];
        [p addAttributeWithName:@"var"stringValue:@"muc#roomconfig_changesubject"];//允许改变主题
        [p addChild:[NSXMLElement elementWithName:@"value"stringValue:@"1"]];
        [x addChild:p];
    
        p = [NSXMLElement elementWithName:@"field" ];
        [p addAttributeWithName:@"var"stringValue:@"muc#roomconfig_publicroom"];//公共房间
        [p addChild:[NSXMLElement elementWithName:@"value"stringValue:@"0"]];
        [x addChild:p];
    
        p = [NSXMLElement elementWithName:@"field" ];
        [p addAttributeWithName:@"var"stringValue:@"muc#roomconfig_allowinvites"];//允许邀请
        [p addChild:[NSXMLElement elementWithName:@"value"stringValue:@"1"]];
        [x addChild:p];
    
        [xmppRoom configureRoomUsingOptions:x];
    }

    6.XMPPRoom的代理方法

    XMPPRoom 相关的代理方法也有很多个,可以在XMPPRoomDelegate中看到,我在下面介绍几个常用的代理方法,其他的大家可以自己去XMPPRoomDelegate中查看。

    6.1 创建群成功的代理方法

    创建成功的代理方法一般都是调试用,实际场景应该是创建群,并且自己加入群成功之后才提醒创建成功。

    - (void)xmppRoomDidCreate:(XMPPRoom *)sender
    {
        NSLog(@"房间创建成功");
    }

    6.2 加入群组成功的代理方法

    创建者加入群之后,就可以设置一些群的参数信息了。

    - (void)xmppRoomDidJoin:(XMPPRoom *)sender
    {
        NSLog(@"加入房间成功");
        // 一般就是在这里设置群组的一些参数
        [self configNewRoom:sender];
    
        [sender fetchConfigurationForm];
        [sender fetchBanList];
        [sender fetchMembersList];
        [sender fetchModeratorsList];
    }

    6.3 查看群组的配置信息

    调用XMPPRoom 的 {-fetchConfigurationForm},然后就可以在下面这个回调方法中获取群组的配置信息

    - (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm
    {
        NSLog(@"configForm:%@",configForm);
    }

    插入知识

    在XMPP 里有 角色、岗位和权限三个概念。

    角色有那些呢?

    这里写图片描述

    岗位有哪些呢?

    已定义的岗位有:
    1. 所有者
    2. 管理员
    3. 成员
    4. 被排斥者
    5. 无(缺少岗位)

    权限又哪些呢?
    大部分情况下, 岗位存在一个层次结构. 例如, 一个所有者可以做任何管理员能做的事情, 而一个管理员可以做任何成员能做的事情. 每个岗位拥有其下一级岗位所没有的权限; 这些权限定义在下表中。

    这里写图片描述

    作为缺省值, 一个无岗位的用户进入一个被主持的房间的角色是一个游客, 而进入一个开放的房间的角色是一个与会者. 一个成员进入一个房间的角色是与会者. 一个管理员或所有者进入房间的角色是一个主持人.
    一个管理员或所有者不能(MUST NOT)撤销另一个管理员或所有者的权限.

    6.4 查找被群组拉黑,禁止加群的成员列表

    调用XMPPRoom 的{-fetchBanList},然后就可以在下面这个代理方法中获取到被禁止的名单列表了

    // 收到禁止名单列表
    - (void)xmppRoom:(XMPPRoom *)sender didFetchBanList:(NSArray *)items
    {
        NSLog(@"%s",__func__);
    }
    
    // 获取禁止名单列表失败
    - (void)xmppRoom:(XMPPRoom *)sender didNotFetchBanList:(XMPPIQ *)iqError
    {
        NSLog(@"%s",__func__);
    }

    6.5 获取群成员列表

    这里写图片描述

    从上图可以看出,一个群组里的所有人员,按照一般需求,除了Member,剩下的Admin 和Owner 都可以归为Moderator 这一类。

    同样的,调用XMPPRoom 的{-fetchMembersList},就可以在如下代理方法中获取群成员列表

    // 收到成员名单列表
    - (void)xmppRoom:(XMPPRoom *)sender didFetchMembersList:(NSArray *)items
    {
        NSLog(@"%s",__func__);
    }
    
    // 获取群成员列表失败
    - (void)xmppRoom:(XMPPRoom *)sender didNotFetchMembersList:(XMPPIQ *)iqError
    {
        NSLog(@"%s",__func__);
    }

    6.6 获取Moderators列表

    调用XMPPRoom 的{-fetchModeratorsList}方法,然后在代理方法中能够获取到列表。

    // 收到主持人名单列表
    - (void)xmppRoom:(XMPPRoom *)sender didFetchModeratorsList:(NSArray *)items
    {
        NSLog(@"%s",__func__);
    }
    
    // 获取主持人名单列表失败
    - (void)xmppRoom:(XMPPRoom *)sender didNotFetchModeratorsList:(XMPPIQ *)iqError
    {
        NSLog(@"%s",__func__);
    }

    Demo地址:ChatDemo

  • 相关阅读:
    英特尔®oneAPI简介及动手实验研讨会召集令
    发展壮大:帮助独立游戏开发商解决分销难题
    我们可以从英特尔® SPMD 程序编译器中学到什么?
    2019 Unreal Open Day —— 英特尔携手 UE 助力游戏开发生态建设
    Abp集成Quartz.net记录
    静态和实例初始化映射
    Queryable扩展点
    投影
    空类型映射
    列表和数组
  • 原文地址:https://www.cnblogs.com/wanghang/p/6298839.html
Copyright © 2020-2023  润新知