編輯:關於Android編程
最近公司項目需要,要做一個自己的IMSDK,順便先把之前沒有記錄的群聊功能記錄一下。
先上資料,查看XMPP群聊相關的資料,可以去這裡看協議:XEP-0045 。
XMPP 框架裡有一個類XMPPRoom,利用這個類可以很容易的創建一個新的群組。
群組的JID與用戶的JID有一些區別。
用戶的JID規則是
群組的JID規則是
而群組的subdomain 是需要提前在服務器端設置好的。
1.1創建群組的服務
如何創建群組服務呢?
在openfire 後台---> 分組聊天--->分組聊天設置中可以看到
創建新的服務按鈕。不知道的看下圖:
1.2 創建群組JID
怎麼寫群組的JID呢?
舉個例子,如果我們要創建一個叫做abc 的群組,而我們的群組服務subdomain是group,而domain 是
im.joker.cn,那麼這個群組的JID就是
[email protected]。
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. 無(缺少崗位)
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxjb2RlPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160908/20160908091839336.png" title="\" />權限又哪些呢?
大部分情況下, 崗位存在一個層次結構. 例如, 一個所有者可以做任何管理員能做的事情, 而一個管理員可以做任何成員能做的事情. 每個崗位擁有其下一級崗位所沒有的權限; 這些權限定義在下表中。
作為缺省值, 一個無崗位的用戶進入一個被主持的房間的角色是一個游客, 而進入一個開放的房間的角色是一個與會者. 一個成員進入一個房間的角色是與會者. 一個管理員或所有者進入房間的角色是一個主持人.
一個管理員或所有者不能(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
在工作中,有一個這樣的需求,需要用到WebView與javascript進行交互,下面我們就通過一個簡單的需求來介紹.先看一下效果圖: 需求:1.點
在上篇文章Android 源碼系列之<十>從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(上)中我們講解了通過Acces
設計思路:1.畫柱狀圖2.畫豎線3.畫頂部橫線4.畫文字1.畫柱狀圖畫柱狀圖的方法很簡單,就是使用canvas.drawRect(float left, float to
先上效果圖: 我這裡用的是GifCam來制作的gif動畫,可以在http://download.csdn.net/detail/baidu_nod/7628461下載