C++利用第三方通信库hvlib实现websocket通信

1 篇文章 0 订阅
1 篇文章 0 订阅
文章介绍了如何使用第三方库hvlib进行WebSocket通信。提供了hvlib的下载链接,以及服务端和客户端的C++代码实现,包括打开连接、发送和接收消息的回调函数。在服务端,当接收到消息时,会调用回调函数将数据传递给界面。客户端则负责建立连接、发送消息和接收回调。文章还提示,如果使用Qt作为前端界面,需要使用信号和槽机制以队列方式连接回调,避免崩溃问题。
摘要由CSDN通过智能技术生成
hvlib是一个第三方库,里面包含各种通信协议,利用库可以很方便的实现网络通信,下面是利用hvlib实现的websocket通信
hvlib源码地址:https://download.csdn.net/download/Pailugou/64827333?spm=1001.2014.3001.5503
hvlib编译库64位:https://download.csdn.net/download/Pailugou/64827902?spm=1001.2014.3001.5503
服务端代码实现:
#pragma once
#include "WebSocketServer.h"
#include "hssl.h"
#include "WebSocket.h"
#include "EventLoop.h"
#include "htime.h"

#include <functional>

using namespace hv;
class HVWebSocket
{
public:
	explicit HVWebSocket(const int port);
	~HVWebSocket();

	void sendMsg(const std::string Msg);

	//接收消息回调,用于将数据发送到界面
	std::function<void(std::string)> m_pMsgCallBack;
private:
	void openWebSocket(const WebSocketChannelPtr& channel, const std::string& req);

	void onMessage(const WebSocketChannelPtr& channel, const std::string& msg);

	void onClose(const WebSocketChannelPtr& channel);

	void serverRun();

	void timerCallBack(TimerID id);
private:
	int m_iPort;

	WebSocketService m_ws;

	websocket_server_t m_wst;

	//用于通信
	WebSocketChannelPtr m_channelPtr;

	//定时器回调接口
	std::function<void(TimerID)> m_pTimerCallBack;

	
};

#include "HVWesocket.h"

HVWebSocket::HVWebSocket(const int port)
	: m_iPort(port)
{
	m_ws.onopen = std::bind(&HVWebSocket::openWebSocket, this, std::placeholders::_1, std::placeholders::_2);
	m_ws.onmessage = std::bind(&HVWebSocket::onMessage, this, std::placeholders::_1, std::placeholders::_2);
	m_ws.onclose = std::bind(&HVWebSocket::onClose, this, std::placeholders::_1);

	m_pTimerCallBack = std::bind(&HVWebSocket::timerCallBack, this, std::placeholders::_1);
	this->serverRun();
}

HVWebSocket::~HVWebSocket()
{
	m_pMsgCallBack = nullptr;
	m_channelPtr->close();
}


void HVWebSocket::openWebSocket(const WebSocketChannelPtr& channel, const std::string& str)
{
	std::cout << "onopen: Get " << str << std::endl;
	m_channelPtr = channel;
	setInterval(1000, m_pTimerCallBack);
}

void HVWebSocket::onMessage(const WebSocketChannelPtr& channel, const std::string& str)
{
	std::cout << "服务端收到消息:" << str << std::endl;
	if (m_pMsgCallBack)m_pMsgCallBack(str);
}

void HVWebSocket::onClose(const WebSocketChannelPtr& channel)
{
	channel->close();
}

void HVWebSocket::serverRun()
{
	m_wst.port = m_iPort;
	m_wst.ws = &m_ws;

	//第二个参数为:0直接内部开启单独线程,不阻塞主线程的运行
	websocket_server_run(&m_wst, 0);
	if (m_pMsgCallBack)m_pMsgCallBack("服务开启...");
}

void HVWebSocket::sendMsg(const std::string msg)
{
	m_channelPtr->send(msg);
}

void HVWebSocket::timerCallBack(TimerID id)
{
	if (m_channelPtr->isConnected())
	{
		char time[DATETIME_FMT_BUFLEN] = { 0 };
		datetime_t datetime = datetime_now();
		datetime_fmt(&datetime, time);
		m_channelPtr->send(time);
	}
	else
	{
		killTimer(id);
	}
}


客户端实现代码:
#pragma once
#include "WebSocketClient.h"

using namespace hv;
class WebClient
{
public:
	explicit WebClient(const int port, const std::string host = "127.0.0.1");

	void sendMsg(std::string msg);

	void close();

	std::function<void(std::string)> m_pMsgCallBack;
private:
	void onClose();

	void onOpen();

	void onMsg(const std::string& msg);
private:
	WebSocketClient* m_client;

	int m_port;
	std::string m_hostAdress;

	
};

#include "WebClient.h"
WebClient::WebClient(const int port, const std::string host)
	: m_port(port)
	, m_hostAdress(host)
{
	m_client = new WebSocketClient();
	m_client->onopen = std::bind(&WebClient::onOpen, this);
	m_client->onmessage = std::bind(&WebClient::onMsg, this, std::placeholders::_1);
	m_client->onclose = std::bind(&WebClient::onClose, this);

	std::string url = "ws://" + host + ":" + std::to_string(port) + "/echo";
	m_client->open(url.c_str());
}

void WebClient::onMsg(const std::string& msg) 
{
	std::cout << "客户端收到消息:" << msg << std::endl;
	if (m_pMsgCallBack)m_pMsgCallBack(msg);
}

void WebClient::onClose()
{
	std::cout << "WS client closeed" << std::endl;
}

void WebClient::onOpen()
{
	std::cout << "WS client opened" << std::endl;
	if (m_pMsgCallBack)m_pMsgCallBack(u8"客户端开启...");
}

void WebClient::sendMsg(const std::string msg)
{
	if (m_client)m_client->send(msg);
}

void WebClient::close()
{
	if (m_client)m_client->close();
	m_pMsgCallBack = nullptr;
}

如果使用Qt作为前段界面,在使用function将数据回调到界面,然后要用信号在转发一下,以队列的方式连接,不然会出现崩溃的现象
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pailugou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值