XMPP框架使用之搜索协议

废话:最近一段时间由于项目需要研究了一下xmpp框架,个人认为如果想使用xmpp框架,他的相关扩展协议是你必须要搞清楚的。例如本片文章要讲的搜索协议,我们知道框架扩展里面是没有原生搜索扩展的,而且网上也很难搜到现成的比较好用的扩展封装类。这样你想要实现这些功能你就要清楚的理解扩展协议,其实学懂了一个协议,你会发现xmpp所有模块的协议,理解起来都差不多,也就是说一通则全通。

主题:搜索协议即 http://xmpp.org/extensions/xep-0055.html ,这里我就不摘抄大量的内容了(最讨厌写博客到处copy),自己去看看吧。

功能:这里所说的搜索协议主要是对服务器用户进行搜索,比如qq,要想加某一个用户为好友,需要先查找这个用户,然后搜出用户的信息,然后添加好友。这个查找功能就是用搜索协议实现的。(当然qq肯定不会用xmpp)

说了这么多,下面看是在代码中实现这个搜索功能。

首先查看一下你的openfire 服务器是否已经安装search插件:

如下图红色标记位置:


服务器端已经提供了用户搜索功能,我们看一下服务器端的搜索功能是怎样的:

如下图:


看了服务器的搜素功能,已经很清楚,我们在客服端实现的搜索功能也是用到search插件实现的,所以也是这样的参数和结果。

客户端代码实现:

看过前面的协议,我们知道客户端与服务器端的交互是通过xml数据流交互的。那么我们首先要知道搜索请求的数据流,根据几个参数和搜索协议不难写出如下搜索请求:

<?xml version="1.0"?>
<iq id="search2" to="sh.m.tie1tie.com" type="set">
    <query xmlns="jabber:iq:search">
        <x type="submit" xmlns="jabber:x:data">
            <field type="hidden" var="FORM_TYPE">
                <value>jabber:iq:search</value>
            </field>
            <field type="text-single" var="search">
                <value><span style="color:#ff6666;">774</span></value>
            </field>
            <field type="boolean" var="Username">
                <value>1</value>
            </field>
            <field type="boolean" var="Name">
                <value>1</value>
            </field>
            <field type="boolean" var="Email">
                <value>1</value>
            </field>
        </x>
    </query>
</iq>

id = "search2"这个是搜索info,search1 是搜索fields;

to =“sh.m.tie1tie.com”这个是搜索服务器的名称,admin控制台 - 服务器 - 服务器设置 - search service propertis下面查看搜索的服务名称

红色字体是搜索的关键字,可以是username,name,email。

在代码中封装这个数据流,即搜索方法的实现:

- (void)searchUserInfo:(NSString *)searchValue
{
    NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
    [iq addAttributeWithName:@"type" stringValue:@"set"];
    XMPPJID *myJID = self.xmppStream.myJID;
    [iq addAttributeWithName:@"from" stringValue:myJID.description];
    [iq addAttributeWithName:@"to" stringValue:@"sh.m.tie1tie.com"];
    [iq addAttributeWithName:@"id" stringValue:@"search2"];
    
    NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:search"];
    NSXMLElement *x = [NSXMLElement elementWithName:@"x" xmlns:@"jabber:x:data"];
    [x addAttributeWithName:@"type" stringValue:@"submit"];
    
    NSXMLElement *field1 = [NSXMLElement elementWithName:@"field"];
    [field1 addAttributeWithName:@"type" stringValue:@"hidden"];
    [field1 addAttributeWithName:@"var" stringValue:@"FROM_TYPE"];
    NSXMLElement *value1 = [NSXMLElement elementWithName:@"value" stringValue:@"jabber:iq:search"];
    [field1 addChild:value1];
    
    NSXMLElement *field2 = [NSXMLElement elementWithName:@"field"];
    [field2 addAttributeWithName:@"type" stringValue:@"text-single"];
    [field2 addAttributeWithName:@"var" stringValue:@"search"];
    NSXMLElement *value2 = [NSXMLElement elementWithName:@"value" stringValue:searchValue];
    [field2 addChild:value2];
    
    NSXMLElement *field3 = [NSXMLElement elementWithName:@"field"];
    [field3 addAttributeWithName:@"type" stringValue:@"boolean"];
    [field3 addAttributeWithName:@"var" stringValue:@"Username"];
    NSXMLElement *value3 = [NSXMLElement elementWithName:@"value" stringValue:@"1"];
    [field3 addChild:value3];
    
    NSXMLElement *field4 = [NSXMLElement elementWithName:@"field"];
    [field4 addAttributeWithName:@"type" stringValue:@"boolean"];
    [field4 addAttributeWithName:@"var" stringValue:@"Name"];
    NSXMLElement *value4 = [NSXMLElement elementWithName:@"value" stringValue:@"1"];
    [field4 addChild:value4];
    
    NSXMLElement *field5 = [NSXMLElement elementWithName:@"field"];
    [field5 addAttributeWithName:@"type" stringValue:@"boolean"];
    [field5 addAttributeWithName:@"var" stringValue:@"Email"];
    NSXMLElement *value5 = [NSXMLElement elementWithName:@"value" stringValue:@"1"];
    [field5 addChild:value5];
    
    [x addChild:field1];
    [x addChild:field2];
    [x addChild:field3];
    [x addChild:field4];
    [x addChild:field5];
    
    [query addChild:x];
    
    [iq addChild:query];
    
    [self.xmppStream sendElement:iq];
}

如此便完成了向服务器搜索用户信息的功能,然后们在代理里面解析返回的result(也是xml数据流)就可以得到结果了。


补充说明:

上面我们讲了如何请求info,接下来我们看一下结果处理:

<?xml version="1.0"?>
<iq xmlns="jabber:client" type="result" id="search1" from="sh.m.tie1tie.com" to="000000000326@m.tie1tie.com/spark”>
    <query xmlns="jabber:iq:search”>
    <span style="white-space:pre">	</span><instructions>The following fields are available for searching. Wildcard (*) characters are allowed as part of the query.</instructions>
    <span style="white-space:pre">	</span><first />
    <span style="white-space:pre">	</span><last />
    <span style="white-space:pre">	</span><nick />
    <span style="white-space:pre">	</span><email />
    <span style="white-space:pre">	</span><x xmlns="jabber:x:data" type="hidden">
       <span style="white-space:pre">	</span>    <value>jabber:iq:search</value>
       <span style="white-space:pre">	</span>    <field var="search" type="text-single" label="Search">
            <required />
      <span style="white-space:pre">	</span>    </field>
            <field var="Username" type="boolean" label="Username">
            <span style="white-space:pre">	</span><value>1</value>
            </field>
            <field var="Name" type="boolean" label="Name">
            <span style="white-space:pre">	</span><value>1</value>
            </field>
            <field var="Email" type="boolean" label="Email">
         <span style="white-space:pre">	</span><value>1</value>
            </field>
   <span style="white-space:pre">	</span> </x>
    </query>
</iq>
这个iq是在

- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
代理方法中获取的iq结果,我们从中获取我们需要的信息。

//返回用户信息查询结果
    if ([@"result" isEqualToString:iq.type] && [[iq attributeStringValueForName:@"id"] isEqualToString:@"search2"]) {
        NSString *name;
        XMPPJID *jid;
        NSXMLElement *query = iq.childElement;
        if ([@"query" isEqualToString:query.name]) {
            NSXMLElement *x = [self childElement:query];
            NSArray *elements = [x children];
            for (NSXMLElement *item in elements) {
                if ([item.name isEqualToString:@"item"]) {
                    NSArray *fields = [item children];
                    for (NSXMLElement *field in fields) {
                        if ([[field attributeStringValueForName:@"var"] isEqualToString:@"Name"]) {
                            name = [[[field elementsForName:@"value"] firstObject] stringValue];
                        }
                        if ([[field attributeStringValueForName:@"var"] isEqualToString:@"jid"]) {
                            NSString *jidStr = [[[field elementsForName:@"value"] firstObject] stringValue];
                            jid = [XMPPJID jidWithString:jidStr];
                        }
                    }
                }
            }
        }
        [self handlePresence:jid name:name];
        
    }

这样我们就完成了结果处理。


PS:所有的功能都可以这样实现!





  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值