XMPPFramework - 实现群聊(MUC)

19

我正在开发iOS聊天客户端,有人能帮我处理多用户聊天吗?

我已经实现了Robbie Hanson的XMPPFramework。

有人能告诉我如何使用这个框架获得群组列表并在服务器上创建群组吗?

提前感谢。


大家好,感谢你们和Stack Overflow的帮助,我已经成功创建了一个群组,并且可以使用核心数据和内存存储发送邀请给其他人。问题是当我创建第二个群组时,它会从核心数据存储中删除第一个群组的数据。另外,我们如何自动加入其他用户? - Mangesh
3个回答

38

获取房间列表:

NSString* server = @"chat.shakespeare.lit"; //or whatever the server address for muc is
XMPPJID *servrJID = [XMPPJID jidWithString:server];
XMPPIQ *iq = [XMPPIQ iqWithType:@"get" to:servJID];
[iq addAttributeWithName:@"from" stringValue:[xmppStream myJID].full];
NSXMLElement *query = [NSXMLElement elementWithName:@"query"];
[query addAttributeWithName:@"xmlns" stringValue:@"http://jabber.org/protocol/disco#items"];
[iq addChild:query];
[xmppStream sendElement:iq];

检查委托方法中的响应:

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq{
    DDLogVerbose(@"%@", [iq description]);
    return NO;
}

加入或创建房间

XMPPRoomMemoryStorage * _roomMemory = [[XMPPRoomMemoryStorage alloc]init];
NSString* roomID = @"roomExample@chat.shakespeare.lit";
XMPPJID * roomJID = [XMPPJID jidWithString:roomID];
XMPPRoom* xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:_roomMemory
                                             jid:roomJID
                                   dispatchQueue:dispatch_get_main_queue()];
[xmppRoom activate:self.xmppStream];
[xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
[xmppRoom joinRoomUsingNickname:@"myNickname"
                        history:nil
                       password:nil];

检查 XMPPRoom 代理方法中的响应:

- (void)xmppRoomDidCreate:(XMPPRoom *)sender{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

- (void)xmppRoomDidJoin:(XMPPRoom *)sender{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);
}

更新

配置房间:

之后:

[xmppRoom joinRoomUsingNickname:self.xmppStream.myJID.user
                        history:history
                       password:nil];

添加:

[xmppRoom fetchConfigurationForm];

并检查响应:

- (void)xmppRoom:(XMPPRoom *)sender didFetchConfigurationForm:(NSXMLElement *)configForm{
    DDLogVerbose(@"%@: %@ -> %@", THIS_FILE, THIS_METHOD, sender.roomJID.user);
}

检查 configForm 对象,根据需要进行更改,然后使用 [sender configureRoomUsingOptions:newConfig]; 发送它。

示例: 如果要更改配置以使房间持久化,可以添加类似以下内容:

NSXMLElement *newConfig = [configForm copy];
NSArray* fields = [newConfig elementsForName:@"field"];
for (NSXMLElement *field in fields) {
    NSString *var = [field attributeStringValueForName:@"var"];
    if ([var isEqualToString:@"muc#roomconfig_persistentroom"]) {
        [field removeChildAtIndex:0];
        [field addChild:[NSXMLElement elementWithName:@"value" stringValue:@"1"]];
    }
}
[sender configureRoomUsingOptions:newConfig];

(我不熟悉NSXMLElement,所以可能有更好的方法来更改值)


1
谢谢你的回答,它对我有用。你能告诉我如何设置不同类型的房间吗?我想创建一个持久的房间,就像 WhatsApp 中的群组一样,可以邀请人并聊天。如果你有任何想法,请告诉我。 - Satish
1
请查看[xmppRoom configureRoomUsingOptions:(NSXMLElement *)roomConfigForm]。要创建所需的房间配置的NSXMLElement,请参考:链接,还可以查看示例159。 - Flores Robles
感谢您的评论,Flores。我确实查看了服务器文档并阅读了其中的内容,但是无法理解如何进行配置。我尝试了通过表单进行配置,但没有效果。如果您有代码或其他文档,将会是很大的帮助... - Satish
感谢您的评论Flores,它确实帮了我很多。我有一个代码可以列出所有聊天室,但有没有办法只获取用户创建或加入的房间。 - Satish
@FloresRobles,你能帮我解决这个问题吗?https://stackoverflow.com/questions/44172852/how-to-parse-xmppmessage-element-attribute-and-node-in-xmppframework-with-swif - May Phyu
显示剩余4条评论

3
这里是 Swift 版本:
func joinRoom(with jidString: String, delegate: XMPPRoomDelegate) -> XMPPRoom {

    let roomJID = XMPPJID(string: jidString)
    let roomStorage = XMPPRoomCoreDataStorage.sharedInstance()

    let room = XMPPRoom(roomStorage: roomStorage, jid: roomJID, dispatchQueue: DispatchQueue.main)!

        room.activate(xmppStream)

        room.addDelegate(delegate, delegateQueue: DispatchQueue.main)

        // If the room is not existing, server will create one.
        room.join(usingNickname: xmppStream.myJID.user, history: nil)

        return room
    }

    // MUCRoomDelegate
    public func xmppRoomDidCreate(_ sender: XMPPRoom!) {
        print("xmppRoomDidCreate")

        // I prefer configure right after created
        sender.fetchConfigurationForm()
    }

    public func xmppRoomDidJoin(_ sender: XMPPRoom!) {
        print("xmppRoomDidJoin")
    }

    public func xmppRoom(_ sender: XMPPRoom!, didFetchConfigurationForm configForm: DDXMLElement!) {
        print("didFetchConfigurationForm")

        let newForm = configForm.copy() as! DDXMLElement

        for field in newForm.elements(forName: "field") {

            if let _var = field.attributeStringValue(forName: "var") {

                switch _var {
                case "muc#roomconfig_persistentroom":
                    field.remove(forName: "value")
                    field.addChild(DDXMLElement(name: "value", numberValue: 1))

                case "muc#roomconfig_membersonly":
                    field.remove(forName: "value")
                    field.addChild(DDXMLElement(name: "value", numberValue: 1))

                // other configures
                default:
                    break
                }

            }

        }

        sender.configureRoom(usingOptions: newForm)
    }

    public func xmppRoom(_ sender: XMPPRoom!, didConfigure iqResult: XMPPIQ!) {
        print("didConfigure")
    }

你能帮我解决这个问题吗?https://stackoverflow.com/questions/44172852/how-to-parse-xmppmessage-element-attribute-and-node-in-xmppframework-with-swif @dichen - May Phyu

0
+(void)getGroupRooms{
    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_groupChat_Domain_server] elementID:[[[PXMPPManager sharedInstance] xmppStream] generateUUID] child:query];
    [iq addAttributeWithName:@"from" stringValue:[[[PXMPPManager sharedInstance] xmppStream] myJID].full];
    [[[PXMPPManager sharedInstance] xmppStream] sendElement:iq];

//<iq type="get" 
//to="conference.cnr-uat.panamaxil.com" 
//id="DF27F28E-488D-4DAB-AA03-399A4CDE91B3" 
//from="919414184320@cnr-uat.panamaxil.com/iphone">
//<query xmlns="http://jabber.org/protocol/disco#items"/>
//</iq>
}

#pragma - mark XMPPStreamDelegate Methods

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq{
//    NSLog(@"Did receive IQ");

    if([iq isResultIQ])
    {
        if([iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"])
        {
            NSLog(@"Jabber Server's Capabilities: %@", [iq XMLString]);

            NSXMLElement *queryElement = [iq elementForName:@"query" xmlns:@"http://jabber.org/protocol/disco#items"];
            NSArray *items = [queryElement elementsForName:@"item"];
            NSMutableArray *arrGroupName = [[NSMutableArray alloc] init];
            for (NSXMLElement *i in items) {
                NSString *roomName = [i attributeStringValueForName:@"name"];
                NSString *jidString = [i attributeStringValueForName:@"jid"];
                //XMPPJID *jid = [XMPPJID jidWithString:jidString];

                NSDictionary *dict = @{
                                       @"groupName" : roomName,
                                       @"groupJID" : jidString,
                                       };
                [arrGroupName addObject:dict];
            }

            [ConversationsModel saveGroupName:arrGroupName];
        }
    }

    return false;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接