libhv: 🔥 比libevent、libuv更易用的国产网络库,用来开发 TCP/UDP/SSL/HTTP/WebSocket/MQTT 客户端/服务端
Win10,64位
使用cmake-3.26.3和vs2017编译,先用cmake生成vs所需的.sln文件,之后直接用vs2017打开即可编译debug和release版本
http服务端
c++编写,支持get、post方法,支持设置线程数以达到并发效果
tcp服务端
c++编写,支持设置线程数以达到并发效果(实际应用中还需添加边界进行拆包)
tcp类头文件
#ifndef TCPSERVERFROMHV_H
#define TCPSERVERFROMHV_H
#include "hv/TcpServer.h"
/** 基于libhv实现的tcp服务端 */
class TcpServerFromHv
{
public:
TcpServerFromHv();
~TcpServerFromHv();
/** 停止 */
void stop();
/** 开启:成功返回0 */
int start();
/** 基于libhv实现的http服务端实例 */
static TcpServerFromHv &instance();
private:
/** tcp服务端 */
hv::TcpServer *m_hv_TcpServer;
/** 客户端连接情况的回调 */
static void onConnection_callback(const hv::SocketChannelPtr& channel);
/** 收到客户端消息的回调 */
static void onMessage_callback(const hv::SocketChannelPtr& channel, hv::Buffer* buf);
/** 发送给客户端的消息已写完的回调 */
static void onWriteComplete_callback(const hv::SocketChannelPtr& channel, hv::Buffer* buf);
};
#endif
tcp类实现文件
#include "tcpserverfromhv.h"
#include <QDebug>
#include <thread>
static TcpServerFromHv s_TcpServerFromHv = TcpServerFromHv();
TcpServerFromHv::TcpServerFromHv()
{
m_hv_TcpServer = nullptr;
}
TcpServerFromHv::~TcpServerFromHv()
{
stop();
}
TcpServerFromHv &TcpServerFromHv::instance()
{
return s_TcpServerFromHv;
}
void TcpServerFromHv::stop()
{
if(m_hv_TcpServer)
{
m_hv_TcpServer->stop();
delete m_hv_TcpServer;
m_hv_TcpServer = nullptr;
}
}
int TcpServerFromHv::start()
{
stop();
m_hv_TcpServer = new hv::TcpServer();
int ir = m_hv_TcpServer->createsocket(2023);
if(ir < 0)
{
delete m_hv_TcpServer;
m_hv_TcpServer = nullptr;
qDebug() << "m_hv_TcpServer->createsocket fail:ir=" << ir << ",WSAGetLastError()=" << WSAGetLastError();
return -1;
}
m_hv_TcpServer->onConnection = &TcpServerFromHv::onConnection_callback;
m_hv_TcpServer->onMessage = &TcpServerFromHv::onMessage_callback;
m_hv_TcpServer->onWriteComplete = &TcpServerFromHv::onWriteComplete_callback;
m_hv_TcpServer->setThreadNum(10);
m_hv_TcpServer->start();
return 0;
}
void TcpServerFromHv::onConnection_callback(const hv::SocketChannelPtr& channel)
{
std::string peeraddr = channel->peeraddr();
if (channel->isConnected())
qDebug() << *(unsigned int*)&std::this_thread::get_id() << peeraddr.c_str() << "connected,channel->fd=" << channel->fd();
else
qDebug() << *(unsigned int*)&std::this_thread::get_id() << peeraddr.c_str() << "disconnected,channel->fd=" << channel->fd();
}
void TcpServerFromHv::onMessage_callback(const hv::SocketChannelPtr& channel, hv::Buffer* buf)
{
channel->write((const void *)"jiatelin", 8);
qDebug() << *(unsigned int*)&std::this_thread::get_id() << "onMessage:buf->size=" << (int)buf->size() << "buf->data=" << (char*)buf->data();
}
void TcpServerFromHv::onWriteComplete_callback(const hv::SocketChannelPtr& channel, hv::Buffer* buf)
{
qDebug() << *(unsigned int*)&std::this_thread::get_id() << "onWriteComplete:buf->size=" << (int)buf->size() << "buf->data=" << (char*)buf->data();
}
使用的话,直接
TcpServerFromHv::instance().start()开始
TcpServerFromHv::instance().stop()结束
http类头文件
#ifndef HTTPSERVERFROMHV_H
#define HTTPSERVERFROMHV_H
#include "hv/HttpServer.h"
/** 基于libhv实现的http服务端 */
class HttpServerFromHv
{
public:
HttpServerFromHv();
~HttpServerFromHv();
/** 停止 */
void stop();
/** 开启:成功返回0 */
int start();
/** 基于libhv实现的http服务端实例 */
static HttpServerFromHv &instance();
private:
/** http服务 */
HttpService *m_HttpService;
/** http服务端 */
hv::HttpServer *m_hv_HttpServer;
/** get方法回应数据的回调 */
static int get_data_callback(HttpRequest* req, HttpResponse* resp);
/** get方法回应文件的回调 */
static int get_file_callback(HttpRequest* req, HttpResponse* resp);
/** post方法回应的回调 */
static int post_callback(HttpRequest* req, HttpResponse* resp);
};
#endif
http类实现文件
#include "httpserverfromhv.h"
#include <QDebug>
#include <thread>
static HttpServerFromHv s_HttpServerFromHv = HttpServerFromHv();
HttpServerFromHv::HttpServerFromHv()
{
m_HttpService = nullptr;
m_hv_HttpServer = nullptr;
}
HttpServerFromHv::~HttpServerFromHv()
{
stop();
}
HttpServerFromHv &HttpServerFromHv::instance()
{
return s_HttpServerFromHv;
}
void HttpServerFromHv::stop()
{
if(m_hv_HttpServer)
{
m_hv_HttpServer->stop();
delete m_hv_HttpServer;
m_hv_HttpServer = nullptr;
delete m_HttpService;
m_HttpService = nullptr;
}
}
int HttpServerFromHv::start()
{
stop();
m_HttpService = new HttpService();
m_HttpService->GET("/get/data", &HttpServerFromHv::get_data_callback);
m_HttpService->GET("/get/file", &HttpServerFromHv::get_file_callback);
m_HttpService->POST("/post", &HttpServerFromHv::post_callback);
m_hv_HttpServer = new hv::HttpServer(m_HttpService);
m_hv_HttpServer->setPort(8080);
m_hv_HttpServer->setThreadNum(10);
int ir = m_hv_HttpServer->start();
if(ir != 0)
{
delete m_hv_HttpServer;
m_hv_HttpServer = nullptr;
delete m_HttpService;
m_HttpService = nullptr;
qDebug() << "m_hv_HttpServer->start fail:ir=" << ir;
return -1;
}
return 0;
}
int HttpServerFromHv::get_data_callback(HttpRequest* req, HttpResponse* resp)
{
qDebug() << *(unsigned int*)&std::this_thread::get_id() << hv::dump_query_params(req->query_params).c_str();
return resp->Data((char *)"jiatelin", 8);
}
int HttpServerFromHv::get_file_callback(HttpRequest* req, HttpResponse* resp)
{
qDebug() << *(unsigned int*)&std::this_thread::get_id() << hv::dump_query_params(req->query_params).c_str();
return resp->File("F:/ColorTestServer_SchemeDesign/ColorTestServer_SchemeDesign.pdf");
}
int HttpServerFromHv::post_callback(HttpRequest* req, HttpResponse* resp)
{
if(req->content_type != APPLICATION_JSON)
{
int code = HTTP_STATUS_BAD_REQUEST;
resp->Set("code", code);
resp->Set("message", http_status_str((enum http_status)code));
return code;
}
qDebug() << *(unsigned int*)&std::this_thread::get_id() << hv::dump_json(req->GetJson()).c_str();
resp->json["name"] = "jingce";
resp->json["age"] = 7;
return 200;
}
使用方法和tcp一致