C++下跨平台websocket库及使用示例

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:

[
	{
		"IMEi" : "6789999",
		"Token" : "jfkl",
		"Type" : "LORA"
	},
	{
		"IMEi" : "00124b00",
		"Token" : "0",
		"Type" : "xxx"
	},

]

json的解析使用jsoncpp库,可自行安装。 

相关推荐

  1. C++websocket使用示例

    2024-04-28 10:58:02       14 阅读
  2. c++ui

    2024-04-28 10:58:02       36 阅读
  3. Rust 语言中的 GUI

    2024-04-28 10:58:02       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-28 10:58:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-28 10:58:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-28 10:58:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-28 10:58:02       20 阅读

热门阅读

  1. 霍兰德测试助你明确高考专业方向,不再迷茫!

    2024-04-28 10:58:02       16 阅读
  2. PDF分割合并

    2024-04-28 10:58:02       11 阅读
  3. 机器学习之sklearn基础教程

    2024-04-28 10:58:02       13 阅读
  4. Spring通过token获取登录用户信息的方式及优化

    2024-04-28 10:58:02       13 阅读