【问题标题】:MUC How-to with XMPPFrameworkMUC 如何使用 XMPPFramework
【发布时间】:2012-05-09 10:28:33
【问题描述】:

我正在开发一个利用 Robbie Hanson 的 XMPPFramework 的 iOS XMPP 聊天应用程序。

最重要的功能已经实现 - 发送和接收消息。基本上,我已经构建了一个基本的功能性聊天应用程序,当然还有一些花哨的东西。

现在,我遇到的问题是关于 MUC。我从其他网站看到的代码显示XMPPRoom中有一个方法initWithRoomName。但是,我克隆的 git repo 中没有这种方法。那么,有什么替代方法呢?或者,如果没有,我该如何使用 XMPPFramework 创建房间?

谢谢。

【问题讨论】:

标签: ios objective-c xmpp xmppframework


【解决方案1】:

以下是我如何解决自己的问题。请注意,此解决方案根本不涉及 XMPPRoom。首先,我创建了一个方法,根据情况创建或进入房间。 (根据 XMPP 文档,用于创建的 XML 请求与您发送以进入房间的请求相同;也就是说,如果房间在您进入时尚不存在,则服务将为您创建它.)

我们开始吧。这是创建/进入房间的方法。此方法的作用是将存在发送到您打算创建/进入的房间。如果您是第一个进入房间但尚未创建房间的人,您将自动成为其所有者和管理员。

- (void)createOrEnterRoom:(NSString *)roomName
{
//here we enter a room, or if the room does not yet exist, this method creates it
//per XMPP documentation: "If the room does not yet exist, the service SHOULD create the room"
//this method accepts an argument which is what you would baptize the room you wish created
NSXMLElement *presence = [NSXMLElement elementWithName:@"presence"];
NSString *room = [roomName stringByAppendingString:@"@conference.jabber.com/iMac"];
[presence addAttributeWithName:@"to" stringValue:room];
 NSXMLElement *x = [NSXMLElement elementWithName:@"x" xmlns:@"http://jabber.org/protocol/muc"];
NSXMLElement *history = [NSXMLElement elementWithName:@"history"];
 [history addAttributeWithName:@"maxstanzas" stringValue:@"50"];
 [x addChild:history];
 [presence addChild:x];
 [[self xmppStream] sendElement:presence];
}

接下来,在声明 XMPPStream 方法的 AppDelegate 中,我们通过检查服务器发送的状态代码来过滤我们在 didReceivePresence 方法中收到的 XML 响应。如果状态码是 201,宾果!房间创建进行得很好。 201 以外的状态码表示不同的含义,但为了我们的目的,让我们关注 201。

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
{
     NSXMLElement *x = [presence elementForName:@"x" xmlns:@"http://jabber.org/protocol/muc#user"];
    for (NSXMLElement *status in [x elementsForName:@"status"])
    {
        switch ([status attributeIntValueForName:@"code"])
        {
            case 201: [self notifyRoomCreationOk:room];
        }
    }
 }

然后,我们告诉服务器我们正在创建一个“即时”类型的房间,这意味着我们将发送一个 IQ 元素告诉它房间默认值。 notifyRoomCreationOk 是房间创建成功时在不同视图中调用的委托方法,毕竟我必须将房间记录在文本文件中以使其持久化,以便下次打开应用程序时可以看到我之前创建的房间。在我的 notifyRoomCreationOk 方法中,我有 sendDefaultRoomConfig,它基本上描述了本段第一句中所述的内容。

-(void)sendDefaultRoomConfig:(NSString *)room
{
NSXMLElement *x = [NSXMLElement elementWithName:@"x" xmlns:@"jabber:x:data"];
[x addAttributeWithName:@"type" stringValue:@"submit"];
NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"http://jabber.org/protocol/muc#owner"];
[query addChild:x];
XMPPIQ *iq = [XMPPIQ iq];
[iq addAttributeWithName:@"id" stringValue:[NSString stringWithFormat:@"inroom-cr%@", room]];
[iq addAttributeWithName:@"to" stringValue:room];
[iq addAttributeWithName:@"type" stringValue:@"set"];
[iq addChild:query];
[[self xmppStream ] sendElement:iq];
}

确保您在调用上述方法的视图上启用了 XMPPStream,否则这些方法将不起作用。这里的所有都是它的。玩得开心 XMPP!

【讨论】:

  • 嘿@Ten Go,你能分享一些示例代码吗?这对我来说非常紧急......提前谢谢
  • @Suresh.D,你在创建一个房间吗?我有一个建议:阅读xmpp.org/extensions/xep-0045.html 中的文档,以便了解整个房间创建过程是如何进行的。一开始这很棘手,但是一旦您了解了房间创建顺序,您就会发现它非常简单。然后,将我上面写的代码插入你的应用程序中。
  • 是的,我按照你说的做了,但是代码状态总是返回0。但是当我使用一对一聊天时,代码状态会返回12。
  • 之后我应该怎么做才能在这个群里添加朋友或邀请朋友加入这个群
  • 我收到三个状态码。 jabber.org/protocol/muc#user"><itemjid="918727050600@yaye.com/yaye" affiliation="owner" role="moderator">
【解决方案2】:
    XMPPRoom *room = [[XMPPRoom alloc] initWithRoomName:@"user101@conference.jabber.org/room" nickName:@"room"];
    [room createOrJoinRoom];
    [room sendInstantRoomConfig];
    [room setInvitedUser:@"ABC@jabber.org"];
    [room activate:[self xmppStream]];    
    [room inviteUser:jid1 withMessage:@"hello please join."];
    [room sendMessage:@"HELLO"];

用户 ABC@jabber.org 应该会收到邀请消息

【讨论】:

  • 感谢您的回答,但这与我尝试过的代码相同。 XMPPFramework 的当前主分支中没有方法“initWithRoomName”。我到处寻找这种特殊的方法无济于事。请告诉您如何设法获得此方法以及您使用的是哪个版本的框架?你能指出我可以从中获取它(框架)的链接吗?如果我有正确的分支,我可以从那里管理它。谢谢。
  • @TenGo r ü bilding 聊天应用程序用于本地连接还是远程连接?
  • 我正在构建的应用程序在互联网上运行,因为它将被世界另一端的队友使用。
  • @TenGo,XMPPRoom 确实包含在框架中,只是有点难找。这是路径:XMPP/Extensions/XEP-0045/XMPPRoom.h
  • @greenhouse 我正在寻找的标头深埋在 repo 附带的分支中。我只是在修补 Git 之后才弄明白。通过遵循 xmpp.org 上的文档并手动创建我在上面的答案中描述的 XML,我能够创建一个多用户房间。
【解决方案3】:

你的帖子很旧,但现在我会这样做:

- (void)createRoomWithJid:(XMPPJID*)roomJID
{
    XMPPRoom *xmppRoom = [[XMPPRoom alloc] initWithRoomStorage:self.xmppRoomHybridStorage
                                                           jid:roomJID
                                                 dispatchQueue:dispatch_get_main_queue()];
    [xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
    [xmppRoom activate:self.xmppStream];

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

【讨论】:

    【解决方案4】:

    使用 XMPPFRAMWORK 通过以下代码创建聊天室。

        let roomStorage: XMPPRoomMemoryStorage = XMPPRoomMemoryStorage()
        /**
         * Remember to add 'conference' in your JID like this:
         * e.g. uniqueRoomJID@conference.yourserverdomain
         */
        let roomJID: XMPPJID = XMPPJID.jidWithString("chatRoom_name@conference.myhostname")
        let xmppRoom: XMPPRoom = XMPPRoom(roomStorage: roomStorage,
            jid: roomJID,
            dispatchQueue: dispatch_get_main_queue())
        xmppRoom.activate(SKxmpp.manager().xmppStream)
        xmppRoom.addDelegate(self, delegateQueue: dispatch_get_main_queue())
        xmppRoom.joinRoomUsingNickname(SKxmpp.manager().xmppStream.myJID.user, history: nil, password: nil)
        xmppRoom.fetchConfigurationForm()
    

    【讨论】:

    • 请编辑更多信息。不鼓励使用纯代码和“试试这个”的答案,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。我们在这里努力成为知识的资源。
    猜你喜欢
    • 2017-05-03
    • 2017-06-29
    • 2012-06-01
    • 2016-02-06
    • 2013-09-04
    • 2013-10-16
    • 2011-10-10
    • 2016-05-23
    相关资源
    最近更新 更多