最近公司项目需要,要做一个自己的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

XMPP系列(六)---创建群组的更多相关文章

  1. Office 365系列六 ------ 创建sharepoint online网站

    这节跟大家介绍简单的创建sharep online私有网站集,sharepoint online 可以给我们提供开箱即用的功能,比如文档库:可以给我们取代File Server,提供了版本管理,版本变 ...

  2. Centos 7搭建Gitlab服务器以及操作(创建项目,创建群组,创建用户,添加密钥)

    一. 安装并配置依赖包 在CentOS系统上安装所需的依赖:ssh,防火墙,postfix(用于邮件通知) ,wget,以下这些命令也会打开 系统防火墙中的HTTP和SSH端口访问 安装前准备 命令: ...

  3. XMPP系列(七)---获取群组列表

    上一篇介绍了如何创建群组,这一篇就介绍一下,如何获取自己的群组列表. 在上一篇有提到,如果我们创建的群组是公共的群组,那么获取自己的群组列表时,会获取到自己的群组列表和那些公共的群组.而实际做社交的应 ...

  4. Linux 的账号与群组[转自vbird]

    Linux 的账号与群组 管理员的工作中,相当重要的一环就是『管理账号』啦!因为整个系统都是你在管理的, 并且所有一般用户的账号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务 ...

  5. Linux学习之CentOS(十)----Linux 的账号与群组

    Linux 的账号与群组 管理员的工作中,相当重要的一环就是『管理账号』啦!因为整个系统都是你在管理的, 并且所有一般用户的账号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务 ...

  6. 详解CorelDRAW中关于群组的操作

    CorelDRAW软件中的“群组”功能键主要用于整合多个对象.在进行比较复杂的绘图编辑时,通常会有很多的图形对象,为了方便操作,可以对一些对象设定群组.设定群组以后的多个对象,将被看作一个单独的对象. ...

  7. linux基础-第六单元 用户、群组和权限

    用户及passwd文件 /etc/passwd文件的功能 /etc/passwd文件每个字段的具体含义 shadow文件 /etc/shadow文件的功能 /etc/shadow文件每个字段的具体含义 ...

  8. linux基础命令--groupadd 创建新的群组

    描述 groupadd命令用于创建一个新的群组. groupadd命令默认会根据命令行指定的值和系统下的/etc/login.defs文件定义的值去修改系统下的/etc/group和/etc/gsha ...

  9. sql server 备份与恢复系列六 文件组备份与还原

    一. 概述 文件备份是指备份一个或多个文件或文件组中的所有数据.使用文件备份能够只还原损坏的文件,而不用还原数据库的其余部份,从而加快恢复速度.例如,如果数据库由位于不同磁盘上的若干文件组成,在其中一 ...

随机推荐

  1. (MariaDB/MySQL)之DML(1):数据插入

    本文目录: 1.insert和replace插入数据 1.1 insert into values() 1.2 insert into set 1.3 insert into select_state ...

  2. [HNOI2010]弹飞绵羊

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  3. hdu 3948 后缀数组

    The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (J ...

  4. 【集训第三天·疯狂训练】哦,顺带学习了manacher

    虽然说是疯狂训练吧,但是也没写多少题,就把伸展树的操作熟悉了一下,ac了5个题目. 一整天没啥可吐槽的,除了昨天在机房打游戏的某位朋友翻车后和教练谈了谈心2333 说题吧.. 1.BZOJ1208 H ...

  5. Django+nginx+uwsgi部署教程(centos7+ubuntu16.4)

    在线教育平台项目演示地址 项目部署教程 1.1.工作原理介绍 django 一个基于python的开源web框架 uwsgi 一是一个web服务器,也可以当做中间件 nginx 常用高性能代理服务器 ...

  6. Python paramik

    本节内容 paramiko模块 1.paramiko模块 Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 Python的paramiko模块,该模块机遇SSH用于 ...

  7. Python【第四课】 装饰器

    本篇内容 什么是装饰器 装饰器需要遵循的原则 实现装饰器的知识储备 高阶函数 函数嵌套 闭包函数 无参函数 装饰器示例 1.什么是装饰器 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本 ...

  8. cmake 没有那个目录

    问题:bash: /usr/bin/cmake: 没有那个文件或目录 因为直接使用cmake系统回到默认的/usr/bin中去寻找,但是src中安装的cmake是在/usr/local/bin中,所以 ...

  9. C语言程序设计第二次作业1

    (一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. ************* Welcome ************* 源程序 include int mian() { printf(&q ...

  10. GC机制

    java虚拟机中的垃圾回收机制是,一个类,当该对象没有更多的应用指向它时,就会被垃圾回收器给回收,从而释放资源.该机制不可以程序员手动调用去回收某个对象,系统自动会去调用,当然程序员可以建议垃圾回收器 ...