创建 xmpp muc 房间时遇到问题:代码 503(服务不可用) [英] Trouble creating xmpp muc room: Code 503 (service unavailable)

查看:14
本文介绍了创建 xmpp muc 房间时遇到问题:代码 503(服务不可用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建房间的代码:

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(服务不可用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆