C++:gloox库进行协议扩展(使用自定义标签)
生活随笔
收集整理的這篇文章主要介紹了
C++:gloox库进行协议扩展(使用自定义标签)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
直接使用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'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库进行协议扩展(使用自定义标签)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: char[] 和char*之间的相互转换
- 下一篇: Python 基本语法规则