基于QT+Boost环境下的websocketpp客户端开发

1 前言

最近工作中需要基于QT写一个websocket的客户端,因为服务器是用websocketpp做的,所以客户端也采用同一个框架,避免通讯中出现异常。

如果使用websocketpp,必需先安装boost环境。

整个开发环境版本:boost_1_80_0 + vs2017 + QT5.12.8

2 boost编译

2.1 下载地址

Boost Downloads

boost有很多版本,一开始用的是boost_1_68_0 加 vs2010编译,后面在websocketpp编译的时候,存在异常。

最后换成boost_1_80_0,使用vs2017进行编译,QT版本为5.12.8

2.2 编译方法

步骤1:解压

解压后命令行进入boost_1_80_0文件夹内,执行:

.\bootstrap.bat

如果不指定编译器版本,就会用默认配置来编译。

如果默认配置是VS2019,但是想用VS2017编译,则命令行输入:

.\bootstrap.bat vc14

具体参数可以参见bootstrap.bat文件。

步骤2:文件路径

编译之后,QT开发需要的文件路径为:

  • include: boost_1_80_0\boost
  • lib :boost_1_80_0\stage\lib 

步骤3:QT环境配置

将boost文件夹和lib文件夹放在qt工程根目录,和pro文件同级。 

在qt的pro文件中增加

3 websocketpp

websocketpp是一个基于C11标准开发的websocket c++框架,源码地址为https://github.com/zaphoyd/websocketpp  

从官网上下载源码,解压后将源码和pro文件同级。

在pro文件中添加头文件引用如下:

4 基于QT的websocketpp客户端开发

4.1 WebsocketClient.h文件

#ifndef WEBSOCKTHREAD_H
#define WEBSOCKTHREAD_H

#include <QObject>
#include <QThread>
#include <QDebug>
#include <QFile>
#include <QIODevice>
#include <QTime>
#include <QTimer>
#include <QString>
#include <QHostAddress>
#include <QDateTime>

#include <queue>
#include <websocketpp/client.hpp>
#include <websocketpp/config/asio_no_tls_client.hpp>

typedef websocketpp::client<websocketpp::config::asio_client> chat_client;

using websocketpp::lib::placeholders ::_1;

using websocketpp::lib::placeholders ::_2;

using websocketpp::lib ::bind;

typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
 


class WebsockThread : public QThread
{
    Q_OBJECT
public:


    explicit WebsockThread(QString serverAddr,QObject *parent = nullptr);
    ~WebsockThread();
    void  startClient();
    void  initClient();
    void sendData(QByteArray data);
   
  

    void run();
    void on_open(chat_client* client, websocketpp::connection_hdl hdl) ;
    void on_close(chat_client* c, websocketpp::connection_hdl hdl);
    void on_message(chat_client* client, websocketpp::connection_hdl hdl,chat_client::message_ptr msg_ptr);
    void on_termination(chat_client* c, websocketpp::connection_hdl hdl);

    chat_client m_client;
    chat_client::connection_ptr m_con;
    bool m_bConnect;
    QString m_strAddr;

signals:
    void signal_sendMsg(  QString msg);
  
 
 
};
#endif // WEBSOCKTHREAD_H

 4.2 WebsocketClient.cpp文件

#include "websockthread.h"

 

void WebsockThread::on_open(chat_client* client, websocketpp::connection_hdl hdl) {


    chat_client::connection_ptr  con = client->get_con_from_hdl(hdl);

    if(con->get_ec().value()!=0){
        m_bConnect = false;
    }else{
        m_bConnect = true;
    }
}




void WebsockThread::on_message(chat_client* client, websocketpp::connection_hdl hdl,chat_client::message_ptr msg_ptr) {

    chat_client::connection_ptr  con = client->get_con_from_hdl(hdl);
    if(msg_ptr->get_opcode() == websocketpp::frame::opcode::text){
        QString msg = msg_ptr->get_payload().c_str();
        emit  signal_sendMsg(text);
    }
}


void WebsockThread::on_close(chat_client* c, websocketpp::connection_hdl hdl) {

    m_bConnect=false;
}

void WebsockThread::on_termination(chat_client* c, websocketpp::connection_hdl hdl)
{


}

WebsockThread::WebsockThread(QString serverAddr,QObject *parent )
    :m_strAddr(serverAddr),QThread(parent)
{
   
    m_bConnect = false;
   
}



/**
* @brief  线程入口
* @argc   null
*/
void WebsockThread::run(){
    initClient();
    startClient();
}

void  WebsockThread::initClient(){

    m_client.clear_access_channels(websocketpp::log::alevel::frame_header);
    m_client.clear_access_channels(websocketpp::log::alevel::frame_payload);
    m_client.set_error_channels(websocketpp::log::elevel::none);

    m_client.init_asio();

    m_client.set_reuse_addr(true);
   
    m_client.set_open_handler(bind(&WebsockThread::on_open, this,&m_client, ::_1));
    m_client.set_message_handler(bind(&WebsockThread::on_message, this,&m_client, ::_1, ::_2));
    m_client.set_close_handler(bind(&WebsockThread::on_close, this, &m_client, ::_1));

}

void WebsockThread::startClient(){

    websocketpp::lib::error_code ec;
  
    m_con = m_client.get_connection(m_strAddr.toStdString(), ec);
    if (ec) {
        qDebug()<< "could not create connection because: "  ;
        return  ;
    }
    m_con->set_termination_handler(bind(&WebsockThread::on_termination, this, &m_client, ::_1));
    m_client.connect(m_con);
    m_client.run();
}

void WebsockThread::sendData(QByteArray data){
    if(m_bConnect){
        m_con->send(data.toStdString(),websocketpp::frame::opcode::BINARY);
    }
}


WebsockThread::~WebsockThread(){

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值