0

我正在使用适用于 iOS/OSX 的 XMPP 框架开发 iPhone 应用程序,并且正在使用 XEP-0045 扩展(多用户聊天)。我已经成功创建和配置了房间,我可以邀请其他用户并与他们聊天。当我去破坏我创建的房间时,问题就出现了。我已经遵循了在框架内执行的代码路径,并且我已经弄清楚了为什么框架没有触发该方法,但是我不确定鉴于我所看到的行为它会如何触发该方法.

该行为如下:

1) 我要求通过调用 [room destroyRoom] 来销毁房间

2) 然后我看到 XMPPRoom 类设置了它的 XMPPIDResponse 跟踪器来监视服务器将发回的“结果” iq 节,说它已成功删除房间。

3)(这里是问题出现的地方)我从房间收到一个出席信息节,说它现在不可用(因为我也是房间的居住者)然后框架清除响应跟踪器并调用 -xmppRoomDidLeave:。

4) 服务器然后发回“结果” iq 节,说房间已成功删除,但没有人再听了。这会导致错过对 xmppRoomDidDestroy 的调用。

这种行为与我在 XEP-0045 定义中所读到的一致,鉴于此,我不确定如何调用 -xmppRoomDidDestroy: 委托。我在这里做错了吗?

4

2 回答 2

0

我有同样的问题,这是我的解决方案:

在 XMPPRoom 方法中

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence

代替

[responseTracker removeAllIDs];

和:

if ([x elementForName:@"destroy"]) {
    NSArray *allKeys = [responseTracker allIDs];
    for (NSString *key in allKeys) {
        SEL aSel = [responseTracker selectorForElementID:key];
        if (aSel != @selector(handleDestroyRoomResponse:withInfo:)) {
            [responseTracker removeID:key];
        }
    }
} else {
    [responseTracker removeAllIDs];
}

在 XMPPIDTracker.h 中添加新公共方法的声明

- (NSArray *)allIDs;

- (SEL)selectorForElementID:(NSString *)elementID;

同样在 XMPPBasicTrackingInfo 接口中添加

@property (nonatomic, readonly) SEL selector;

在 XMPPIDTracker.m 添加两个公共方法

- (NSArray *)allIDs {
    return [dict allKeys];
}

- (SEL)selectorForElementID:(NSString *)elementID {
    id <XMPPTrackingInfo> info = [dict objectForKey:elementID];
    if ([info isKindOfClass:[XMPPBasicTrackingInfo class]]) {
        return [(XMPPBasicTrackingInfo *)info selector];
    }
    return nil;
}

在@implementation XMPPBasicTrackingInfo 的末尾添加

@synthesize selector;

基本上,这段代码删除了除了 handleDestroyRoomResponse:withInfo: 之外的所有响应跟踪器,因为我们需要这个处理程序来响应 IQ 销毁节。

我希望这将有所帮助。

于 2014-03-10T14:58:04.163 回答
0

与 lastest 相同的问题XMPPFramework 3.6.6

这是解决方案:

仍然使用destroyRoom函数,xmppStream:didReceivePresence:并将xmppRoomDidLeave:被调用,通过NSLog在两个委托中添加测试,然后我使用 Spark(Windows 版本)破坏一个房间,Xcode 控制台打印以下文本:

<presence xmlns="jabber:client" type="unavailable" from="wei@conference.10.50.200.94/admin" to="admin@10.50.200.94/iOS">
    <x xmlns="http://jabber.org/protocol/muc#user">
        <item affiliation="none" role="none"></item>
        <destroy>
            <reason>destroy room</reason>
        </destroy>
    </x>
</presence>

我使用<destroy>元素来确定destroyRoom动作。

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
    /*
     <presence xmlns="jabber:client" type="unavailable" from="wei@conference.10.50.200.94/admin" to="admin@10.50.200.94/iOS"><x xmlns="http://jabber.org/protocol/muc#user"><item affiliation="none" role="none"></item><destroy><reason>destroy room</reason></destroy></x></presence>
     */
    // NSLog(@"%s %@", __FUNCTION__, presence);
    if ([presence.fromStr containsString:@"conference"]) {
        NSXMLElement *x = [presence elementForName:@"x"];
        if (x) {
            NSXMLElement *destroy = [x elementForName:@"destroy"];
            if (destroy) {
                XMPPJID *roomJID = presence.from.bareJID;
                // TODO: do something with the roomJID
            }
        }
    }
}

但是XMPPFramework发送一个空<destory/>元素,我猜openfire服务器只是忽略了并且没有<destroy/>响应。<presence>..</presence><destroy>

修改中的destroyRoom函数XMPPFramework或实现以下委托以添加销毁原因。

- (XMPPIQ *)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq
{
    /*
     <iq type="set" to="weixin@conference.10.50.200.94" id="BCF55C6A-9C5E-4740-BE6A-63E17B5C58F6"><query xmlns="http://jabber.org/protocol/muc#owner"><destroy></destroy></query></iq>
     */
    if ([iq isSetIQ]) {
        NSXMLElement *query = [iq elementForName:@"query" xmlns:XMPPMUCOwnerNamespace];
        if (query) {
            NSXMLElement *destroy = [query elementForName:@"destroy"];
            if (destroy) {
                NSXMLElement *reason = [destroy elementForName:@"reason"];
                if (!reason) {
                    reason = [NSXMLElement elementWithName:@"reason" stringValue:@"destroy reason"];
                    [destroy addChild:reason];
                }
            }
        }
    }
    return iq;
}
于 2016-12-14T06:37:10.593 回答