websocketpp介绍

websocketpp是一个只有头文件的支持websocket协议的C++开源库,支持websocket客户端和服务器功能,网络传输模块基于boost::asio

提供 server 功能的 websocketpp::server 和提供 client 功能的 websocketpp:client 都继承自基类 websocketpp::endpoint , endpoint提供了一些通用的功能函数:

void set_access_channels(log::level channels);//设置日志级别
void clear_access_channels(log::level channels)//屏蔽某个级别的日志 void set_open_handler(open_handler h);//设置打开连接时的回调函数
void set_close_handler(close_handler h);//设置关闭连接时的回调函数
void set_fail_handler(fail_handler h);//设置连接失败时的回调函数
void set_message_handler(message_handler h);//设置收到消息时的回调函数

服务器代码

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp> #include <functional> typedef websocketpp::server<websocketpp::config::asio> server; class utility_server {
public:
utility_server() {
// 设置log
m_endpoint.set_error_channels(websocketpp::log::elevel::all);
m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload); // 初始化Asio
m_endpoint.init_asio(); // 设置消息回调为echo_handler
m_endpoint.set_message_handler(std::bind(
&utility_server::echo_handler, this,
std::placeholders::_1, std::placeholders::_2
));
} void echo_handler(websocketpp::connection_hdl hdl, server::message_ptr msg) {
// 发送消息
m_endpoint.send(hdl, msg->get_payload(), msg->get_opcode());
} void run() {
// 监听端口 9002
m_endpoint.listen(9002); m_endpoint.start_accept(); // 开始Asio事件循环
m_endpoint.run();
}
private:
server m_endpoint;
}; int main() {
utility_server s;
s.run();
return 0;
}

运行后执行到 s.run() 当前线程会进入Asio的消息循环,可以调用s.top()退出

客户端代码

#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream> typedef websocketpp::client<websocketpp::config::asio_client> 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; void on_open(client *c, websocketpp::connection_hdl hdl)
{
std::string msg = "hello";
c->send(hdl, msg, websocketpp::frame::opcode::text);
c->get_alog().write(websocketpp::log::alevel::app, "Tx: " + msg);
} void on_message(client *c, websocketpp::connection_hdl hdl, message_ptr msg)
{
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
websocketpp::lib::error_code ec;
//c->send(hdl,msg->get_payload(),msg->get_opcode(),ec);
if(ec)
{
std::cout << "Echo failed because " << ec.message() << std::endl;
}
} //定时器回调函数
void Timeout(client *c, websocketpp::connection_hdl &hdl, boost::asio::deadline_timer *pt, const boost::system::error_code &ec)
{
if(ec)
{
std::cout << "timer is cancel " << std::endl;
return;
}
static int count = 0;
c->send(hdl, "hello", websocketpp::frame::opcode::text);
count++;
if(count > 5)//定时器触发五次后关闭连接
{
c->close(hdl, websocketpp::close::status::normal, "");
return;
}
pt->expires_at(pt->expires_at() + boost::posix_time::seconds(5));
pt->async_wait(bind(Timeout, c, hdl, pt, ::_1)); } int main(int argc, char *argv[])
{
client c; std::string uri = "ws://xx.xx.xx.xx:xxx"; c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.clear_access_channels(websocketpp::log::alevel::frame_header); // 初始化 ASIO
c.init_asio(); // 注册消息回调 c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));
c.set_open_handler(bind(&on_open, &c, _1)); websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
con->add_subprotocol("janus-protocol");
if(ec)
{
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
} auto hdl = con->get_handle();
c.connect(con); boost::asio::deadline_timer t(c.get_io_service(), boost::posix_time::seconds(5)); //设置一个5s超时的定时器
t.async_wait(bind(&Timeout, &c, hdl, &t, ::_1)); std::thread th([&c] { c.run(); }); //休眠13s后取消定时器并关闭连接
sleep(13);
t.cancel();
c.close(hdl, websocketpp::close::status::normal, ""); th.join();
}

我们可以利用 Asio 的一些其它组件,如定时器等;初始化定时器传入 c.get_io_service() 在一个io循环中处理定时事件和其它事件

当客户端调用 close 关闭连接时,则自动退出c.run()开启的循环

重复关闭和打开连接

#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <iostream> typedef websocketpp::client<websocketpp::config::asio_client> client; using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2; typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
class connection
{
public: void on_open(websocketpp::connection_hdl hdl)
{
std::string msg = "hello";
c.send(hdl, msg, websocketpp::frame::opcode::text);
c.get_alog().write(websocketpp::log::alevel::app, "Tx: " + msg);
} void on_message(websocketpp::connection_hdl hdl, message_ptr msg)
{
std::cout << "on_message called with hdl: " << hdl.lock().get()
<< " and message: " << msg->get_payload()
<< std::endl;
websocketpp::lib::error_code ec;
if(ec)
{
std::cout << "Echo failed because " << ec.message() << std::endl;
}
} int init()
{
uri = "ws://xx.xx.xx.xx:xx"; c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.clear_access_channels(websocketpp::log::alevel::frame_header); c.init_asio(); c.set_message_handler(websocketpp::lib::bind(&connection::on_message, this,::_1, ::_2));
c.set_open_handler(websocketpp::lib::bind(&connection::on_open, this, _1)); c.start_perpetual();
thread_=websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run,&c); } void connect()
{
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if(ec)
{
std::cout << "could not create connection because: " << ec.message() << std::endl;
return ;
} hdl_ = con->get_handle();
c.connect(con); }
void close()
{
c.close(hdl_, websocketpp::close::status::normal, "");
} void terminate()
{
c.stop_perpetual();
thread_->join();
}
private:
client c;
websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread_;
websocketpp::connection_hdl hdl_;
std::string uri; };

需要重复打开关闭连接时,只调用一次init_asio()函数,然后调用start_perpetual()将endpoint设置为永久的,不会在连接断开时自动退出。需要结束循环,调用stop_perpetual()

使用websocketpp进行websocket通信的更多相关文章

  1. C#(SuperWebSocket)与websocket通信

    原文:C#(SuperWebSocket)与websocket通信 客户端代码 点击可以查看一些关于websocket的介绍 <!DOCTYPE html> <html> &l ...

  2. js判断是否安装某个android app,没有安装下载该应用(websocket通信,监听窗口失去焦点事件)

    现在经常有写场景需要提示用户下载app, 但是如果用户已经安装,我们希望是直接打开app. 实际上,js是没有判断app是否已经安装的方法的,我们只能曲线救国. 首先,我们需要有call起app的sc ...

  3. Springboot集成WebSocket通信全部代码,即扣即用。

    websocket通信主要来自两个类以及一个测试的html页面. MyHandler 和 WebSocketH5Config,下面全部代码 MyHandler类全部代码: package com.un ...

  4. 【Java Web开发学习】Spring MVC整合WebSocket通信

    Spring MVC整合WebSocket通信 目录 ========================================================================= ...

  5. websocket通信1009错误,

    问题说明: springboot继承 WebSocketConfigurer实现websocket通信服务,服务器端报错,"The decoded text message was too ...

  6. Python3+WebSockets实现WebSocket通信

    一.说明 1.1 背景说明 前段时间同事说云平台通信使用了个websocket的东西,今天抽空来看一下具体是怎么个通信过程. 从形式上看,websocket是一个应用层协议,socket是数据链路层. ...

  7. webSocket通信

    针对webSocket通信总结: 1.webSocket通信原理图: 2.webSocket通信实例 参考地址1:https://www.cnblogs.com/cjm123/p/9674506.ht ...

  8. 把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造异步非阻塞(aioredis)实时(websocket)通信聊天系统

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_202 "表达欲"是人类成长史上的强大"源动力",恩格斯早就直截了当地指出,处在蒙昧时代即低 ...

  9. websocket通信 实现java模拟一个client与webclient通信

    发文原由: 熟悉socket通信的同学,对于socket模拟server与client,实现相互通信, 或者使用websocket与java模拟的websocket服务器通信(比如一个聊天室),对于这 ...

随机推荐

  1. 基于Spark的电影推荐系统(推荐系统~2)

    第四部分-推荐系统-数据ETL 本模块完成数据清洗,并将清洗后的数据load到Hive数据表里面去 前置准备: spark +hive vim $SPARK_HOME/conf/hive-site.x ...

  2. 微信小程序发起请求

    一.示例代码 wx.request({ url: 'test.php', // 仅为示例,并非真实的接口地址 data: { x: '', y: '' }, header: { 'content-ty ...

  3. 程序员成长的四个简单技巧,你 get 了吗?

    最近拜读了"阿里工程师的自我修养"手册,12 位技术专家分享生涯感悟来帮助我们这些菜鸡更好的成长,度过中年危机,我收获颇多,其中有不少的方法技巧和我正在使用的,这让我觉得我做的这些 ...

  4. [插件化开发] Poc之后,我选择放弃OSGI

    Poc之后,我选择放弃OSGI TIPS: 如贵司允许重构老系统或者允许使用OSGI的第三方框架改造所带来的投入成本,并且评估之后ROI乐观,那么还是可以使用的. Runtime Version 以下 ...

  5. 利用hash远程登陆系统

    有的时候当我们拿到系统管理员hash由于密码复杂度过高无法破解时候可以利用hash直接进行远程登录 我们用到Metasploit里面的模块 肉鸡为windwos server 2003 x32系统 1 ...

  6. 6.Linux文件属性及软硬链接

    1.文件属性 使用ll -h 查看的详细信息,每一列都是干什么的 第一列第一个字符 表示文件类型---> rw-r--r-- 文件权限 1 这个文件被链接次数 root 文件的拥有者(用户) r ...

  7. 算法问题实战策略 QUADTREE

    地址 https://algospot.com/judge/problem/read/QUADTREE 将压缩字符串还原后翻转再次压缩的朴素做法 在数据量庞大的情况下是不可取的 所以需要在压缩的情况下 ...

  8. 玩转PubSubClient MQTT库

    1.前言     在ESP8266学习系列中,博主一直使用HTTP协议.HTTP连接属于短连接,而在物联网应用中,广泛应用的却是MQTT协议.所以,本篇我们将学习Arduino平台上的MQTT实现库 ...

  9. 【阿里云IoT+YF3300】7.物联网设备表达式运算

    很多时候从设备采集的数据并不能直接使用,还需要进行处理一下.如果采用脚本处理,有点太复杂了,而采用表达式运算,则很方便地解决了此类问题. 一.  设备连接 运行环境搭建:Win7系统请下载相关的设备驱 ...

  10. 使PC端网页宽度自适应手机屏幕大小

    有时候我们会纠结PC页面在手机页面上无法正常显示,超出屏幕,有些内容看不到,现在又了下面的代码,可以做到自适应手机端的屏幕宽度: 在html的<head>中增加一个meta标签: < ...