websocketpp库使用非常方便,开源,可跨平台,内部实现全部是head文件,无cpp,接口简单易用。源码路径比如 https://github.com/zaphoyd/websocketpp.git
使用方法是,先下载源码包并复制道工程的include目录下。
--include
--websocketpp
然后在代码#include "utility_client.hpp"即可调用其接口进行websocket通信。以linux为例具体使用的方法代码示例:
websockettalker.h:
#ifndef WEBSOCKETTALKER_H
#define WEBSOCKETTALKER_H
#include "dao.h"
#include "utility_client.hpp"
#include "pthread.h"
#include "vector"
using namespace std;
class CloudTalker;
class WebsocketTalker
{
public:
WebsocketTalker(CloudTalker* talker, const string& remoteAddr, const string& name);
~WebsocketTalker();
string GetStatus();
string GetMessage();
bool Subscribe(const string& deviceId, const string& token);
void handleNbData(const string& msg);
private:
CloudTalker* mTalker;
static void* thread_loop(void* pVoid);
pthread_t recv_thread;
websocket_endpoint mEndpoint;
int mId;
string addr = "";
bool should_exit = false;
vector<DevInfo> mImeiTable;
DAO* mDevDbDao = NULL;
};
#endif // WEBSOCKETTALKER_H
websockettalker.cpp:
#include "websockettalker.h"
#include "cloudtalker.h"
#include "udptalker.h"
#include <boost/algorithm/string.hpp>
using namespace boost;
#define JSON_PATH_DEV "path/to/devDB.json"
WebsocketTalker::WebsocketTalker(CloudTalker* talker, const string& remoteAddr, const string& name)
{
string messageclient;
addr = "ws://" + remoteAddr + ":8081/webSocketServer?" + name; //格式为
cout <<"full address is:" <<addr <<endl;
mTalker = talker;
mDevDbDao = new DAO();
pthread_create(&recv_thread, nullptr, thread_loop, this);
}
/***********************************************************
* 描述: 处理数据
* 入参: wholeMsg - 要处理的数据
* 出参: 无
* 返回: 无
************************************************************/
void WebsocketTalker::handleData(const string& wholeMsg)
{
cout <<endl;
}
/***********************************************************
* 描述: websocket通信线程
* 入参: pVoid - WebsocketTalker指针
* 出参: 无
* 返回: 无
************************************************************/
void* WebsocketTalker::thread_loop(void* pVoid)
{
WebsocketTalker* p = (WebsocketTalker*) pVoid;
string status = "";
string wholeMsg = "";
int cont = 0;
unsigned int len = 0;
while(!p->should_exit)
{
p->mImeiTable.clear();
printf("WEBSOCKET WANT TO CREATE CONNECT FOR NBIOT DATA\n");
p->mDevDbDao->getNBAndShareImeiAll(JSON_PATH_DEV, p->mImeiTable);
len = p->mImeiTable.size();
if(len == 0)
{
int cnt = 0;
printf("nb/share dev list is zero\n");
while(!p->should_exit && cnt++ <4)
{
usleep(500000);
}
cnt = 0;
continue;
}
p->mId = p->mEndpoint.connect(p->addr);
if (p->mId == -1)
{
cout << "Created connection failed! mId=" << p->mId<< endl;
}
else
{
while(!p->should_exit)
{
usleep(50000);
status = p->GetStatus();
if(status.length() && status != "Connecting")
break;
}
if(p->should_exit)
{
printf("exit 1\n");
break;
}
for(unsigned int i=0; i<len; i++)
{
cout<<"subscribe dev: " << p->mImeiTable[i].IMEi<< "with token: "<<p->mImeiTable[i].Token<<endl;
p->Subscribe(p->mImeiTable[i].IMEi, p->mImeiTable[i].Token);
cont = 0;
while(!p->should_exit)
{
usleep(50000);
status = p->GetStatus();
if(status == "Message")
break;
if(cont++ > 40)
{
printf("websocket data receive subscribe status timeout\n");
//cont = 0;
break;
}
}
if(p->should_exit || cont > 40)
{
printf("exit 2\n");
break;
}
wholeMsg = p->GetMessage();
printf("[%s(%d)%s] msg=%s\n", __FUNCTION__, __LINE__, __TIME__, wholeMsg.data());
cont = 0;
/*循环接收消息 */
while(!p->should_exit)
{
if(cont++ > 40)
{
printf("websocket data receive timeout\n");
//cont = 0;
break;
}
status = p->GetStatus();
//printf("get status: %s\n", status.c_str());
if(status == "Message")
{
wholeMsg = p->GetMessage();
printf("[%s(%d)%s;] GOT SUBSCRIBED DATA, msg=%s\n", __FUNCTION__, __LINE__, __TIME__, wholeMsg.data());
p->handleNbData(wholeMsg);
cont = 0;
break;
}
usleep(50000);
}
if(p->should_exit)
{
printf("exit 3\n");
break;
}
}
p->mEndpoint.close(p->mId, websocketpp::close::status::normal, "close");
if(p->should_exit)
{
printf("exit 3\n");
break;
}
}
usleep(2000000);//sleep long time could be.
}
return NULL;
}
string WebsocketTalker::GetStatus()
{
return mEndpoint.get_metadata(mId)->get_status();
}
string WebsocketTalker::GetMessage()
{
return mEndpoint.get_metadata(mId)->get_message();
}
bool WebsocketTalker::Subscribe(const string& deviceId, const string& token)
{
string str;
str = "{\"type\":\"address\",\"msg\":\"" + deviceId + "\",\"token\":\"" + token +"\"}";
printf("[%s(%d)] %s\n", __FUNCTION__, __LINE__, str.data());
mEndpoint.send(mId, str);
return true;
}
WebsocketTalker::~WebsocketTalker()
{
printf("exit wstalker\n");
if(mDevDbDao != NULL)
{
delete mDevDbDao;
}
should_exit = true;
pthread_join(recv_thread, NULL);
printf("exit wstalker done\n");
}
dao.h:
#ifndef DAO_H
#define DAO_H
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "json/json.h"
#ifndef UNUSED
#define UNUSED(x) (void)(x)
#endif
using namespace std;
typedef struct
{
string IMEi;
string Type;
string Token;
}DevInfo;
class DAO{
public:
DAO(){}
// 10. get device information transform to <vector> from json, "device information contain {IMEI, type, token, index}"
int getNBAndShareImeiAll(const char* dfile_path, vector<DevInfo>& imeiTable)
{
fstream dev_f;
dev_f.open(dfile_path, ios::in | ios::out);
if (!dev_f.is_open())
{
cout << "Open file error !" << endl;
}
Json::Value val;
Json::Value root_arr;
JSONCPP_STRING errs;
//bool did;
DevInfo devInfo;
Json::CharReaderBuilder rbuilder;
rbuilder["collectComments"] = false;
bool parse_ok = Json::parseFromStream(rbuilder, dev_f, &root_arr, &errs);
if(!parse_ok)
{
cout << "Parse json file error !" << endl;
}
else
{
const Json::Value arrayObj = root_arr;
cout << " ------ Printf Device information: ------ " << endl;
try
{
for (unsigned int i = 0; i < arrayObj.size(); i++)
{
if(arrayObj[i]["Type"].asString() == "LORA")
{
devInfo =
{
arrayObj[i]["IMEi"].asString(),
arrayObj[i]["Type"].asString(),
arrayObj[i]["Token"].asString()
};
imeiTable.push_back(devInfo);
}
}
}
catch (const Json::LogicError &ex)
{
cout << " Parse json string error!" << endl;
}
}
dev_f.close();
return 0;
}
};
#endif // DAO_H
devDB.json:文章来源:https://www.toymoban.com/news/detail-861003.html
[
{
"IMEi" : "6789999",
"Token" : "jfkl",
"Type" : "LORA"
},
{
"IMEi" : "00124b00",
"Token" : "0",
"Type" : "xxx"
},
]
json的解析使用jsoncpp库,可自行安装。 文章来源地址https://www.toymoban.com/news/detail-861003.html
到了这里,关于C++下跨平台websocket库及使用示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!