前言

直接使用gloox库源码中examples下面的示例,采用开源的openfire搭建的xmpp的服务器,是可以直接进行连接、注册和消息推送。 使用AndroidPN作为xmpp服务器可以可以直接使用 gloox的示例进行注册,但是连接 和 消息推送不行。连接的问题咋们就不说了,咋们直接说 消息推送的问题。

因为AndroidPN作为服务器 给客户端推送的消息是扩展了协议,所以直接使用示例代码是不行。笔者也是看官方文档查看 gloox源代码,将这个问题调通了。其实就是Protocol Extensions 协议扩展问题,如果你仔细去看stanzaextension.h也能解决。自己在网上没有找到一个完整的示例,所以在这里本着奉献自我的精神,写一个使用 gloox 进行协议扩展的案例。

下面是AndroidPN服务器给的消息推送报文结构

<iq type='set' id='193-0' to='cotest2@127.0.0.1/gloox'><notification xmlns='androidpn:iq:notification'><id>65d24038</id><apiKey>1234567890</apiKey><title>Dokdo Island</title><message>Dokdo is a Korean island, the far east of the Korean territory. No doubt! No question! Don&apos;t mention it any more!</message><uri>www.baidu.com</uri></notification>
</iq>

我们需要的title、message和uri,我们通过协议扩展来获取到我们想要的信息。

这里额外说下gloox使用的是1.0.22版本AndroidPN服务器使用的是androidpn-server-0.5.0-bin 。

代码

定义我们自己的扩展类

myextension.h

#pragma once#include "stanzaextension.h"
#include <string>
using namespace gloox;class MyExtension :public StanzaExtension
{
public:MyExtension();MyExtension( const Tag* tag );//MyExtension( const MyExtension& one );virtual ~MyExtension();/*** This function returns the embedded Stanza, if any.* You only have to reimplement it if your protocol flow contains embedded Stanzas.** @return The embedded Stanza. May be 0.*/virtual Stanza* embeddedStanza() const { return 0; }/*** This function returns the embedded Tag that the embedded Stanza is based on, if any.* You only have to reimplement it if your protocol flow contains embedded Stanzas.** @return The embedded Tag. May be 0.*/virtual Tag* embeddedTag() const { return 0; }/*** Returns an XPath expression that describes a path to child elements of a* stanza that an extension handles.** @return The extension's filter string.*/virtual const std::string& filterString() const;/*** Returns a new Instance of the derived type. Usually, for a derived class FooExtension,* the implementation of this function looks like:* @code* StanzaExtension* FooExtension::newInstance( const Tag* tag ) const* {*   return new FooExtension( tag );* }* @endcode* @return The derived extension's new instance.*/virtual StanzaExtension* newInstance( const Tag* tag ) const;/*** Returns a Tag representation of the extension.* @return A Tag representation of the extension.*/virtual Tag* tag() const;/*** Returns an identical copy of the current StanzaExtension.* @return An identical copy of the current StanzaExtension.*/virtual StanzaExtension* clone() const;std::string getTitle();std::string getMsg();std::string getUrl();private:std::string m_title;std::string m_msg;std::string m_url;
};

myextension.cpp

#include "myextension.h"
#include "tag.h"
#include "gloox.h"
#include <stdlib.h>
using namespace gloox;#define OPEN_TEST 0MyExtension::MyExtension():StanzaExtension(ExtUser)
{
#if OPEN_TESTprintf("MyExtension() \n");
#endif
}   MyExtension::MyExtension( const Tag* tag ):StanzaExtension(ExtUser)
{/*<notification xmlns='androidpn:iq:notification'><id>65d24038</id><apiKey>1234567890</apiKey><title>Dokdo Island</title><message>Dokdo is a Korean island, the far east of the Korean territory.</message><url>www.baidu.com</url></notification>*/#if OPEN_TESTprintf("MyExtension( const Tag* tag ) enter \n");#endifTag* titleTag = tag->findChild("title");if( NULL != titleTag ){m_title = titleTag->cdata();}Tag* msgTag = tag->findChild("message");if( NULL != titleTag ){m_msg = msgTag->cdata();}Tag* urlTag = tag->findChild("uri");if( NULL != urlTag ){m_url = urlTag->cdata();}
}MyExtension::~MyExtension()
{
#if OPEN_TESTprintf("~MyExtension() \n");
#endif
}// 返回自定义协议的xmlns进行过滤匹配
const std::string& MyExtension::filterString() const
{#if OPEN_TESTprintf("filterString() enter \n");#endifstatic const std::string filter = "/iq/notification[\@xmlns='androidpn:iq:notification']";return filter;
}StanzaExtension* MyExtension::newInstance( const Tag* tag ) const
{#if OPEN_TESTprintf("newInstance( const Tag* tag ) enter \n");#endifStanzaExtension* ret = new MyExtension( tag );return ret;
}Tag*  MyExtension::tag() const
{/*<notification xmlns='androidpn:iq:notification'><id>65d24038</id><apiKey>1234567890</apiKey><title>Dokdo Island</title><message>Dokdo is a Korean island, the far east of the Korean territory.</message><url>www.baidu.com</url></notification>*/#if OPEN_TESTprintf("MyExtension::tag() enter \n");#endifTag* root = new Tag("notification");root->addAttribute("xmlns","androidpn:iq:notification");Tag* titleTag = new Tag("title");Tag* msgTag = new Tag("message");Tag* urlTag = new Tag("uri");titleTag->setCData(m_title);msgTag->setCData(m_msg);urlTag->setCData(m_url);root->addChild(titleTag);root->addChild(msgTag);root->addChild(urlTag);return root;
}StanzaExtension* MyExtension::clone() const
{StanzaExtension* ret = new MyExtension(*this);return ret;
}std::string MyExtension::getTitle()
{return m_title;
}std::string MyExtension::getMsg()
{return m_msg;
}std::string MyExtension::getUrl()
{return m_url;
}

在使用的地方进行注册,并且继承 IqHandler并重写对应的纯虚函数。

    MyExtension* ex = new MyExtension(); // 自定义xmpp协议扩展j->registerIqHandler(this,ExtUser);j->registerStanzaExtension(ex);

重写

virtual bool handleIq( const IQ& iq ) {MyExtension* ex = (MyExtension*)iq.findExtension(ExtUser);if( NULL == ex ){return false;}std::cout <<"title:" << ex->getTitle() << std::endl;std::cout << "msg:" << ex->getMsg() << std::endl; std::cout << "url:" << ex->getUrl() << std::endl;return true;}virtual void handleIqID( const IQ& iq, int context ){return;}

效果截图

C++:gloox库进行协议扩展(使用自定义标签)相关推荐

  1. GB28181开发(二) pjsip库SDP协议扩展

    项目使用pjsip库作为底层协议库,扩展支持GB28181协议,但pjsip的sdp编解码不支持额外参数解析,需要修改源代码,以便支持GB28181中关于SDP协议的扩展(例如y参数).源码主要在pj ...

  2. Java-Web JSTL标签库、自定义标签库和MVC设计模式

    目录 一.JSTL标签库 1.什么是JSTL 2.JSTL标签库 3.使用taglib指令导入标签库 4.core标签库常用标签 (1)out和set (2)remove (3)url (4)if ( ...

  3. java自定义标签库的开发

    java自定义标签库的开发 第14章 自定义标签库的开发 14.1 自定义标签介绍 14.2 HelloWorld标签的开发 14.3 开发带Body的标签库 14.4 多个标签的嵌套 14.5 开发 ...

  4. php taglib.php,thinkphp5 taglib_pre_load预加载自定义标签库

    文章内容来自官方手册,需要查看详细的可以访问来源网址. 模板中加载标签库,预加载自定义标签库,扩展内置标签库的加载 下面以标签库放在common作为一个示例: namespace app\common ...

  5. 深入浅出自定义标签(一)入门

    相信大家在编辑Jsp页面的时候用到过"自定义标签", 自定义标签主要用于调用Javaean组件中的操作和执行请求分派的标准,JSP标签简化了JSP页面的开发和维护.JSP技术还提供 ...

  6. Java第四十八天,Jsp之Taglib,自定义标签详解

    理论知识 一.标签的本质是什么 自定义标签实际上是一个实现了特定接口的Java类,它封装了一些常用功能,在运行时被相应的代码所替换:它与 JavaBean 的最大区别就是 JavaBean 没有默认的 ...

  7. javaweb学习总结(二十三)——jsp自定义标签开发入门

    一.自定义标签的作用 自定义标签主要用于移除Jsp页面中的java代码. 二.自定义标签开发和使用 2.1.自定义标签开发步骤 1.编写一个实现Tag接口的Java类(标签处理器类) 1 packag ...

  8. 如何使用jsp自定义标签 JspTag 使用入门

    java开发中,sturts标签和c标签就是我们常用的两种标签,本文主要教大家如何定义自己的标签,已达到代码整合,公共化的目的.通过jsp自定义标签,可以将一个元素,或者一个表格,一个div甚至整个页 ...

  9. 修改meta标签 查看源码没效果怎么办_Spring 源码学习(三)-自定义标签

    又来填坑啦,上一篇讲完默认标签的解析,这篇笔记记录一下自定义标签的解析吧. 我们知道,Spring 源码的核心模块是 Spring-core 和 Spring-beans,在此基础上衍生出其他模块,例 ...

最新文章

  1. ListBox combobox的常用功能
  2. JAVA 总结(壹)
  3. 1个价值80亿美元的iPod
  4. 互联网日报 | 6月16日 星期三 | 滴滴试点早高峰拼成0佣金计划;小米“急”招自动驾驶相关人才;苹果正式推出播客订阅服务...
  5. Promise的10大知识点!
  6. 为什么我不建议用51单片机仿真软件proteus?
  7. 计算机为啥启用不了网络发现,Win7“网络发现”功能启用不了的原因和解决方法...
  8. 如何在Java中将double转换为int?
  9. 用PGP实现加密和解密全过程
  10. fpu测试_【测试】拯救者Y9000X性能amp;散热数据
  11. 《零基础学Python》Python数据结构【四】
  12. 前端HTML5视频_Less-张晓飞-专题视频课程
  13. 关于机械臂的模仿学习
  14. windows系统下载安装JDK8
  15. 基于UDP心跳监测及邮件提醒功能的看门狗实现
  16. 电脑复制替换目标中覆盖的文件如何恢复?EasyRecovery15
  17. C语言程序设计50行以上,C语言程序设计100例——都卡会了,2级绝对没问题了---2...
  18. 大数据Hadoop学习之——TF-IDF算法实现
  19. 视频倒放怎么制作?视频倒放方法分享。
  20. 假设检验之p值(probability value)

热门文章

  1. Big Sur更新下载过慢?亲测!满速下载macOS原版系统
  2. mathmagic pro mac使用教程|快速地创建任何方程
  3. mac使用的正确操作与注意事项(人体工程学)
  4. 计算机采用二进制形式的表示,计算机部信息的表示及存储往往采用二进制形式,采用这种形式的最主要原因是...
  5. linux启动大叶机制,DPDK-Suricata应用部署
  6. python计算选手最后得分并取出前三名_MySQL中查询获取每个班级成绩前三名的学生信息...
  7. python代码进去docker容器内_python脚本监控docker容器
  8. 除了uni-app可以做app外,flutter更接近原生开发应用
  9. QT Core | 信号槽02 - GUI上按钮触发应用程序的函数(lambda表达式)
  10. Linux基础学习八:mysql主从复制原理以及详细搭建步骤