問題描述
我創建房間的代碼:
XMPPRoomCoreDataStorage *rosterstorage = [[XMPPRoomCoreDataStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:rosterstorage jid:[XMPPJID jidWithString:@"groupchat@xmpp.getkismet.com/groupchat"] dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:[[self appDelegate] xmppStream]];
if ([xmppRoom preJoinWithNickname:@"nameToCreateRoom"])
{
NSLog(@"room created");
[xmppRoom joinRoomUsingNickname:self.userName history:nil];
}
[xmppRoom fetchConfigurationForm];
[xmppRoom configureRoomUsingOptions:nil];
[xmppRoom addDelegate:[self appDelegate] delegateQueue:dispatch_get_main_queue()];
調試:
2012-08-03 07:46:29.204 iPhoneXMPP[9887:fb03] room created
2012-08-03 07:46:29:230 iPhoneXMPP[9887:15003] SEND: <iq type="get" to="groupchat@xmpp.getkismet.com" id="B793062B-0E09-492F-BC0F-703503AAA664"><query xmlns="http://jabber.org/protocol/muc#owner"/></iq>
2012-08-03 07:46:29:237 iPhoneXMPP[9887:15003] SEND: <iq type="set" to="groupchat@xmpp.getkismet.com" id="392D5BFC-707B-4F68-A829-56F949F4E96D"><query xmlns="http://jabber.org/protocol/muc#owner"><x xmlns="jabber:x:data" type="submit"/></query></iq>
2012-08-03 07:46:29:326 iPhoneXMPP[9887:14f03] SEND: <presence to="groupchat@xmpp.getkismet.com"><x xmlns="http://jabber.org/protocol/muc"/><x xmlns="vcard-temp:x:update"><photo>91217a961321f8f6380ea2feefd0632353ad296c</photo></x><c xmlns="http://jabber.org/protocol/caps" hash="sha-1" node="http://code.google.com/p/xmppframework" ver="VyOFcFX6+YNmKssVXSBKGFP0BS4="/></presence>
2012-08-03 07:46:29:327 iPhoneXMPP[9887:14f03] RECV: <iq xmlns="jabber:client" from="groupchat@xmpp.getkismet.com" to="lee@xmpp.getkismet.com/41068195801343976386548353" type="error" id="B793062B-0E09-492F-BC0F-703503AAA664"><query xmlns="http://jabber.org/protocol/muc#owner"/><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
2012-08-03 07:46:29:343 iPhoneXMPP[9887:fb03] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
2012-08-03 07:46:29:421 iPhoneXMPP[9887:15003] RECV: <iq xmlns="jabber:client" from="groupchat@xmpp.getkismet.com" to="lee@xmpp.getkismet.com/41068195801343976386548353" type="error" id="392D5BFC-707B-4F68-A829-56F949F4E96D"><query xmlns="http://jabber.org/protocol/muc#owner"><x xmlns="jabber:x:data" type="submit"/></query><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>
2012-08-03 07:46:29:440 iPhoneXMPP[9887:fb03] iPhoneXMPPAppDelegate: xmppStream:didReceiveIQ:
我看到它正在創建/加入 groupchat@xmpp.getkismet.com 而不是我指定的 groupchat@xmpp.getkismet.com/groupchat.我讀到這很可能是問題所在.但是,我已經指定了完整的 jid,所以我迷路了.
I see that it is creating/joining groupchat@xmpp.getkismet.com and not groupchat@xmpp.getkismet.com/groupchat like I specified. I read that this is most likely the problem. However, I have specified for the full jid, so I'm lost.
提前感謝所有提供幫助的人.
Thanks in advance to all who help.
推薦答案
首先看這里 XEP-0045:多用戶聊天.
如您所見,首先您必須發現您的用戶 (XMPPJID) 在 Jabber 服務器上具有哪些功能.
為此,將下一個命令發送到您的 Jabber 服務器:
First, take look here XEP-0045: Multi-User Chat.
As you can see, first you have to discover which capabilities your user (XMPPJID) has on the Jabber server.
To do this, send next command to your Jabber Server:
<iq from='user@jabber.server.com/resource' id='some_expression' to='jabber.server.com' type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
或使用 XMPP 庫函數在 Objective-C 中編寫:
or writen in objective-c using XMPP library functions:
NSError *error = nil;
NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@"<query xmlns='http://jabber.org/protocol/disco#items'/>"
error:&error];
XMPPIQ *iq = [XMPPIQ iqWithType:@"get"
to:[XMPPJID jidWithString:@"jabber.server.com"]
elementID:[xmppStream generateUUID] child:query];
[xmppStream sendElement:iq];
現在在 XMPPStream 委托中監聽來自服務器的響應 - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
并且服務器響應應該是這樣的:
Now listen response from server in XMPPStream delegate - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
and server response should be something like this:
<iq from='jabber.server.com' id='some_expression' to='user@jabber.server.com/resource' type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='im.jabber.server.com' name='Instant Message Service'/>
<item jid='conference.jabber.server.com' name='Chatroom Service'/>
</query>
</iq>
或目標c:
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
NSLog(@"Jabber Server's Capabilities: %@", [iq XMLString]);
}
}
}
現在,對于返回的每個項目,將 IQ 發送到您的服務器以獲得它的屬性,并確定哪一個是 會議 類型,如下所示:
Now for every item returned send IQ to your server for it's properties and figure out which one is type of conference, something like this:
<iq from='user@jabber.server.com/resource' id='some_expression' to='conference.jabber.server.com' type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
或在目標c中:
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
NSXMLElement *query = [iq childElement];
NSArray *items = [query children];
for(NSXMLElement *item in items)
{
NSError *error = nil;
NSXMLElement *sendQuery = [[NSXMLElement alloc] initWithXMLString:@"<query xmlns='http://jabber.org/protocol/disco#info'/>"
error:&error];
XMPPIQ *sendIQ = [XMPPIQ iqWithType:@"get"
to:[XMPPJID jidWithString:[item attributeStringValueForName:@"jid"]]
elementID:[xmppStream generateUUID]
child:sendQuery];
[xmppStream sendElement:sendIQ];
}
}
}
}
監聽來自服務器的響應:
Listen for responses from server:
<iq from='conference.jabber.server.com' id='some_expression' to='user@jabber.server.com/resource' type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='conference' name='Server Group Chat Service' type='text'/>
<feature var='http://jabber.org/protocol/muc'/>
</query>
</iq>
并從具有category:conference
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
{
if([iq isResultIQ])
{
if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
{
...
}
else if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#info"])
{
NSXMLElement *query = [iq childElement];
NSXMLElement *identity = [query elementForName:@"identity"];
if([[identity attributeStringValueForName:@"category"] isEqualToString:@"conference"])
{
groupChatDomain = [iq fromStr];
}
}
}
}
最后,當我們得到群??聊域后,我們可以像這樣創建聊天室:
Finally, when we got group chat domain we can create chat room something like this:
XMPPJID *chatRoomJID = [XMPPJID jidWithUser:@"chat_room"
domain:groupChatDomain
resource:@"user"];
XMPPRoomMemoryStorage *roomMemoryStorage = [[XMPPRoomMemoryStorage alloc] init];
XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:roomMemoryStorage
jid:roomChatJID
dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:xmppStream];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:user history:nil];
并在您的視圖控制器及其委托中添加 <XMPPRoomDelegate>
協議:
and add <XMPPRoomDelegate>
protocol in your view controller and its delegates:
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
- (void)xmppRoomDidDestroy:(XMPPRoom *)sender
- (void)xmppRoom:(XMPPRoom *)sender didConfigure:(XMPPIQ *)iqResult
- (void)xmppRoom:(XMPPRoom *)sender didNotConfigure:(XMPPIQ *)iqResult
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
- (void)xmppRoomDidLeave:(XMPPRoom *)sender
- (void)xmppRoom:(XMPPRoom *)sender occupantDidJoin:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
- (void)xmppRoom:(XMPPRoom *)sender occupantDidLeave:(XMPPJID *)occupantJID withPresence:(XMPPPresence *)presence
- (void)xmppRoom:(XMPPRoom *)sender didReceiveMessage:(XMPPMessage *)message fromOccupant:(XMPPJID *)occupantJID
注意:在邀請其他用戶加入聊天室之前,您必須發送并確認房間配置(可以邀請其他用戶,但不能發送消息).
因此,您可以在創建 Room 后執行此操作(調用委托 - (void)xmppRoomDidCreate:(XMPPRoom *)sender
)或您的用戶已加入(委托 - (void)xmppRoomDidJoin:(XMPPRoom *)sender
被調用)到聊天室.
要發送和確認房間配置,請執行以下操作之一:
Note: Before inviting other users to Chat Room, you have to send and confirm room configurations (other users can be invited but messages can not be sent).
So you can do this after Room is created (delegate - (void)xmppRoomDidCreate:(XMPPRoom *)sender
is called) or your user has joined (delegate - (void)xmppRoomDidJoin:(XMPPRoom *)sender
is called) to Chat Room.
To send and confirm room configuration do one of the following:
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
{
[sender configureRoomUsingOptions:nil];
}
或
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
[sender configureRoomUsingOptions:nil];
}
發送 nil
以接受默認選項,或者您可以將語法如下的 IQ 發送到您的服務器:
Send nil
to accept default options or you can send IQ with syntax as below to your server:
<iq type='set' from='user@jabber.server.com/resource' id='some_expression' to='chat_room@conference.jabber.server.com'>
<query xmlns='http://jabber.org/protocol/muc#owner'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'>
<value>http://jabber.org/protocol/muc#roomconfig</value>
</field>
<field var='muc#roomconfig_roomname'>
<value>My Chat Room</value>
</field>
.
.
.
<x>
</query>
</iq>
或目標c代碼:
NSError *error = nil;
NSXMLElement *query = [[NSXMLElement alloc] initWithXMLString:@"<query xmlns='http://jabber.org/protocol/muc#owner'/>"
error:&error];
NSXMLElement *x = [NSXMLElement elementWithName:@"x"
xmlns:@"jabber:x:data"];
[x addAttributeWithName:@"type" stringValue:@"submit"];
NSXMLElement *field1 = [NSXMLElement elementWithName:@"field"];
[field1 addAttributeWithName:@"var" stringValue:@"FORM_TYPE"];
NSXMLElement *value1 = [NSXMLElement elementWithName:@"value"
stringValue:@"http://jabber.org/protocol/muc#roomconfig"];
[field1 addChild:value1];
NSXMLElement *field2 = [NSXMLElement elementWithName:@"field"];
[field2 addAttributeWithName:@"var" stringValue:@"muc#roomconfig_roomname"];
NSXMLElement *value2 = [NSXMLElement elementWithName:@"value"
stringValue:@"My Chat Room"];
[field2 addChild:value2];
//Add other fields you need, just like field1 and field2
[x addChild:field1];
[x addChild:field2];
[query addChild:x];
NSXMLElement *roomOptions = [NSXMLElement elementWithName:@"iq"];
[roomOptions addAttributeWithName:@"type" stringValue:@"set"];
[roomOptions addAttributeWithName:@"id" stringValue:[xmppStream generateUUID];
[roomOptions addAttributeWithName:@"to" stringValue:@"chat_room@conference.jabber.server.com"];
[roomOptions addChild:query];
[sender configureRoomUsingOptions:roomOptions];
所有可能的配置表單字段列表是這里
and list of all possible Configuration Form fields is here
這篇關于創建 xmpp muc 房間時遇到問題:代碼 503(服務不可用)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!