Qt编写websocketpp客户端
1、下载websocketpp,地址为https://github.com/zaphoyd/websocketpp,版本为0.7。
2、下载boost,地址为https://www.boost.org/,版本为1.6.3。
3、说明:websocketpp并不是必须需要boost,如果C++编译为C11以上,是可以不用的。
4、Qt创建一个console工程(如:websocketClient),将下载下来的websocket_master里面的websocket文件夹放到该工程目录下,在webSocketClient.pro文件中添加include(websocket/websocket.pri),
5、创建websocket_client类,头文件websocket_client.h内容如下:
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/common/thread.hpp>
#include <websocketpp/common/memory.hpp>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <map>
using namespace websocketpp::lib::placeholders;
typedef websocketpp::client<websocketpp::config::asio_client> client;
class connection_metadata
{
public:
typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;
connection_metadata(websocketpp::connection_hdl hdl, std::string uri)
: m_hdl(hdl)
, m_status("Connecting")
, m_uri(uri)
, m_server("N/A")
{}
void on_open(client *echo_client, websocketpp::connection_hdl hdl)
{
m_status = "Open";
client::connection_ptr con = echo_client->get_con_from_hdl(hdl);
m_server = con->get_response_header("Server");
}
void on_fail(client *echo_client, websocketpp::connection_hdl hdl
{
m_status = "Failed";
client::connection_ptr con = echo_client->get_con_from_hdl(hdl);
m_server = con->get_response_header("Server");
m_error_reason = con->get_ec().message();
}
void on_close(client *echo_client, websocketpp::connection_hdl hdl)
{
m_status = "Closed";
client::connection_ptr con = echo_client->get_con_from_hdl(hdl);
std::stringstream s;
s << "close code: " << con->get_remote_close_code() << " ("
<< websocketpp::close::status::get_string(con->get_remote_close_code())
<< "), close reason: " << con->get_remote_close_reason();
m_error_reason = s.str();
}
void on_message(websocketpp::connection_hdl hdl, client::message_ptr msg)
{
if(msg->get_opcode() == websocketpp::frame::opcode::text)
{
std::cout << "on message called with hdl: " << hdl.lock().get() << "and message: " << msg->get_payload() << std::endl;
m_messages.push_back("<< " + msg->get_payload());
}
else
{
m_messages.push_back("<< " + websocketpp::utility::to_hex(msg->get_payload()));
}
}
websocketpp::connection_hdl get_hdl() const
{
return m_hdl;
}
std::string get_status() const
{
return m_status;
}
std::string get_uri() const
{
return m_uri;
}
void record_sent_message(std::string message)
{
m_messages.push_back(">> " + message);
}
friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
private:
websocketpp::connection_hdl m_hdl;
std::string m_status;
std::string m_uri;
std::string m_server;
std::string m_error_reason;
std::vector<std::string> m_messages;
};
std::ostream & operator<< (std::ostream & out, connection_metadata const & data);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class websocket_client
{
public:
websocket_client();
~websocket_client();
int connect(std::string const & uri);
void close();
void send(std::string message);
void show();
private:
client echo_client;
connection_metadata::ptr Con;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread;
};
websocket_client.cpp文件内容如下:
std::ostream & operator<< (std::ostream & out, connection_metadata const & data)
{
out << "> URI: " << data.m_uri << "\n"
<< "> Status: " << data.m_status << "\n"
<< "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n"
<< "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason) << "\n";
out << "> Messages Processed: (" << data.m_messages.size() << ") \n";
for (std::vector<std::string>::const_iterator it = data.m_messages.begin(); it != data.m_messages.end(); ++it)
{
out << *it << "\n";
}
return out;
}
websocket_endpoint::websocket_endpoint()
{
echo_client.clear_access_channels(websocketpp::log::alevel::all);
echo_client.clear_error_channels(websocketpp::log::elevel::all);
echo_client.init_asio();
echo_client.start_perpetual();
m_thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run, &echo_client);
}
websocket_endpoint::~websocket_endpoint()
{
echo_client.stop_perpetual();
if(Con->get_status() == "Open")
{
websocketpp::lib::error_code ec;
echo_client.close(Con->get_hdl(), websocketpp::close::status::going_away, "", ec);
if(ec)
{
std::cout << "> Error closing ws connection " << Con->get_uri() << " :" << ec.message() << std::endl;
}
}
m_thread->join();
}
int websocket_endpoint::connect(std::string const & uri)
{
websocketpp::lib::error_code ec;
client::connection_ptr pConnection = echo_client.get_connection(uri,ec);
if(ec)
{
std::cout << "> Connect initialization error: " << ec.message() << std::endl;
return -1;
}
Con = websocketpp::lib::make_shared<connection_metadata>(pConnection->get_handle(),uri);
pConnection->set_open_handler(websocketpp::lib::bind(&connection_metadata::on_open,Con,&echo_client,::_1));
pConnection->set_fail_handler(websocketpp::lib::bind(&connection_metadata::on_fail,Con,&echo_client,::_1));
pConnection->set_close_handler(websocketpp::lib::bind(&connection_metadata::on_close,Con,&echo_client,::_1));
pConnection->set_message_handler(websocketpp::lib::bind(&connection_metadata::on_message,Con,::_1,::_2));
echo_client.connect(pConnection);
return 0;
}
void websocket_endpoint::close()
{
if(Con->get_status() == "Open")
{
websocketpp::lib::error_code ec;
echo_client.close(Con->get_hdl(),websocketpp::close::status::normal,"",ec);
if(ec)
{
std::cout << "> Error initiating close: " << ec.message() << std::endl;
}
}
}
void websocket_endpoint::send(std::string message)
{
websocketpp::lib::error_code ec;
echo_client.send(Con->get_hdl(), message, websocketpp::frame::opcode::text, ec);
if(ec)
{
std::cout << "> Error sending messages: " << ec.message() <<std::endl;
return;
}
Con->record_sent_message(message);
}
void websocket_endpoint::show()
{
std::cout << *Con << std::endl;
}
6、运行程序后,在终端输入命令
Enter Command: send 11111111(向服务器发送1111111111)
Enter Command:show(显示websocketpp客户端信息及已经发送和接收的数据)
Enter Command:quit(退出)
Qt编写websocketpp客户端的更多相关文章
- 使用Qt编写服务器端程序(包括Http传输服务器端)的方法
使用Qt编写客户端的程序的示例或demo较多,但是编写服务器端程序的demo很少.当然,服务器端的程序一般不需要带界面,这点我们可以理解.不过有些时候我们还是需要使用Qt编写一个简单的测试用的服务器代 ...
- Qt编写的开源帖子集合(懒人专用)
回顾自己学习Qt以来九年了,在这九年多时间里面,从本论坛学习不到不少的东西,今天特意整了一下自己开源过的资源的帖子,整理一起方便大家直接跳转下载,不统计不知道,一统计吓一跳,不知不觉开源了这么多代码, ...
- Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)
一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...
- Qt编写气体安全管理系统10-数据导出
一.前言 数据导出一般指导出到excel表格,可能有部分用户还需要导出到pdf,因为pdf基本上不可编辑,防止用户重新编辑导出的数据,excel可能绝大部分用过电脑的人都知道,广为流行,主要就是微软的 ...
- Qt编写控件属性设计器9-数据库采集
一.前言 数据库作为数据源,在很多组态软件中使用非常多,指定数据库类型,填写好数据库连接信息,指定对应的数据库表和字段,采集间隔,程序按照采集间隔自动采集数据库数据,绑定到界面上的控件赋值显示即可.使 ...
- Qt编写控件属性设计器8-网络采集
一.前言 上一篇文章已经打通了数据源之一的串口采集,这次要说的是网络采集,网络通信目前用的最多的是三种,TCP/UDP/HTTP,其中tcp通信又包括了客户端服务端两种,tcp通信才用了多次握手机制不 ...
- Qt编写控件属性设计器7-串口采集
一.前言 数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口.网络.数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示. ...
- Qt编写Onvif搜索及云台控制工具
一.前言 这个工具很早以前大概在2013年就想做了,后面杂七杂八的事情一再耽搁,记得当时最初用的是soap类来搜索和解析的,后面发现太大了,每次编译都要等好久,光源码文件加起来都快10MB了,而且函数 ...
- Qt编写自定义控件23-广告轮播控件
一.前言 广告轮播这个控件做的比较早,是很早以前定制一个电信客户端时候用到的,该客户端需要在首页展示轮播预先设定好的图片,图片的路径可以自由设定,然后轮播的间隔速度可以自由控制,同时该控件还需要提供两 ...
随机推荐
- 流媒体技术学习笔记之(十三)Windows安装FFmpeg
一.下载地址: 网址:https://ffmpeg.org/ 选择Windows版本:https://ffmpeg.org/download.html#build-windows 二.解压安装: 下载 ...
- 洛谷 P4838 P哥破解密码 题解
矩阵乘法 + 快速幂优化递推: 看到这个题目我们不难想到递推,题干中说3个连续的A出现在序列中是不合法的,所以可以分为三种情况: (1):序列前只有一个A,如:BA,BBA,BABA. (2):序列前 ...
- (叉积)B - Toy Storage POJ - 2398
题目链接:https://cn.vjudge.net/contest/276358#problem/B 题目大意:和上一次写叉积的题目一样,就只是线不是按照顺序给的,是乱序的,然后输出的时候是按照有三 ...
- C - 青蛙的约会 POJ - 1061 (扩展欧几里得)
题目链接:https://cn.vjudge.net/contest/276376#problem/C 题目大意:中文题目. 具体思路:扩展gcd,具体证明过程看图片(就这麽个题我搞了一天,,,). ...
- 揭开webRTC媒体服务器的神秘面纱——WebRTC媒体服务器&开源项目介绍
揭开webRTC媒体服务器的神秘面纱--WebRTC媒体服务器&开源项目介绍 WebRTC生态系统是非常庞大的.当我第一次尝试理解WebRTC时,网络资源之多让人难以置信.本文针对webRTC ...
- 计算机底层知识拾遗(九)深入理解内存映射mmap
内存映射mmap是Linux内核的一个重要机制,它和虚拟内存管理以及文件IO都有直接的关系,这篇细说一下mmap的一些要点. 修改(2015-11-12):Linux的虚拟内存管理是基于mmap来实现 ...
- mysql5.7.20:安装教程
从mysql官网下载安装包:/mysql-5.7.20-linuxglibc2.12-x86_64.tar.gz #切换目录 cd /usr/local #解压下载的安装包 tar -zxvf /so ...
- cube-ui
cube-ui 新官网:https://didi.github.io/cube-ui/#/zh-CN
- javascript设计模式----桥接模式、组合模式、装饰者模式、享元模式
http://blog.csdn.net/painsonline/article/details/7215087 桥接模式:http://www.cnblogs.com/TomXu/archiv ...
- CF1064B 【Equations of Mathematical Magic】
题目要求解$a-(a\oplus x)-x=0$的解$x$的个数 移项得$a-x=a\oplus x$ $a$的二进制形式,应该是一个$01$串,异或的过程是不能影响到两个不同的位的,所以我们按位考虑 ...