XMPP框架使用之搜索协议

来源:互联网 发布:电子产品销售软件 编辑:程序博客网 时间:2024/06/05 08:19

废话:最近一段时间由于项目需要研究了一下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:所有的功能都可以这样实现!





0 0
原创粉丝点击