websocketpp介绍

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

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

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

服务器代码

  1. #include <websocketpp/config/asio_no_tls.hpp>
  2. #include <websocketpp/server.hpp>
  3. #include <functional>
  4. typedef websocketpp::server<websocketpp::config::asio> server;
  5. class utility_server {
  6. public:
  7. utility_server() {
  8. // 设置log
  9. m_endpoint.set_error_channels(websocketpp::log::elevel::all);
  10. m_endpoint.set_access_channels(websocketpp::log::alevel::all ^ websocketpp::log::alevel::frame_payload);
  11. // 初始化Asio
  12. m_endpoint.init_asio();
  13. // 设置消息回调为echo_handler
  14. m_endpoint.set_message_handler(std::bind(
  15. &utility_server::echo_handler, this,
  16. std::placeholders::_1, std::placeholders::_2
  17. ));
  18. }
  19. void echo_handler(websocketpp::connection_hdl hdl, server::message_ptr msg) {
  20. // 发送消息
  21. m_endpoint.send(hdl, msg->get_payload(), msg->get_opcode());
  22. }
  23. void run() {
  24. // 监听端口 9002
  25. m_endpoint.listen(9002);
  26. m_endpoint.start_accept();
  27. // 开始Asio事件循环
  28. m_endpoint.run();
  29. }
  30. private:
  31. server m_endpoint;
  32. };
  33. int main() {
  34. utility_server s;
  35. s.run();
  36. return 0;
  37. }

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

客户端代码

  1. #include <websocketpp/config/asio_no_tls_client.hpp>
  2. #include <websocketpp/client.hpp>
  3. #include <iostream>
  4. typedef websocketpp::client<websocketpp::config::asio_client> client;
  5. using websocketpp::lib::placeholders::_1;
  6. using websocketpp::lib::placeholders::_2;
  7. using websocketpp::lib::bind;
  8. typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
  9. void on_open(client *c, websocketpp::connection_hdl hdl)
  10. {
  11. std::string msg = "hello";
  12. c->send(hdl, msg, websocketpp::frame::opcode::text);
  13. c->get_alog().write(websocketpp::log::alevel::app, "Tx: " + msg);
  14. }
  15. void on_message(client *c, websocketpp::connection_hdl hdl, message_ptr msg)
  16. {
  17. std::cout << "on_message called with hdl: " << hdl.lock().get()
  18. << " and message: " << msg->get_payload()
  19. << std::endl;
  20. websocketpp::lib::error_code ec;
  21. //c->send(hdl,msg->get_payload(),msg->get_opcode(),ec);
  22. if(ec)
  23. {
  24. std::cout << "Echo failed because " << ec.message() << std::endl;
  25. }
  26. }
  27. //定时器回调函数
  28. void Timeout(client *c, websocketpp::connection_hdl &hdl, boost::asio::deadline_timer *pt, const boost::system::error_code &ec)
  29. {
  30. if(ec)
  31. {
  32. std::cout << "timer is cancel " << std::endl;
  33. return;
  34. }
  35. static int count = 0;
  36. c->send(hdl, "hello", websocketpp::frame::opcode::text);
  37. count++;
  38. if(count > 5)//定时器触发五次后关闭连接
  39. {
  40. c->close(hdl, websocketpp::close::status::normal, "");
  41. return;
  42. }
  43. pt->expires_at(pt->expires_at() + boost::posix_time::seconds(5));
  44. pt->async_wait(bind(Timeout, c, hdl, pt, ::_1));
  45. }
  46. int main(int argc, char *argv[])
  47. {
  48. client c;
  49. std::string uri = "ws://xx.xx.xx.xx:xxx";
  50. c.set_access_channels(websocketpp::log::alevel::all);
  51. c.clear_access_channels(websocketpp::log::alevel::frame_payload);
  52. c.clear_access_channels(websocketpp::log::alevel::frame_header);
  53. // 初始化 ASIO
  54. c.init_asio();
  55. // 注册消息回调
  56. c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));
  57. c.set_open_handler(bind(&on_open, &c, _1));
  58. websocketpp::lib::error_code ec;
  59. client::connection_ptr con = c.get_connection(uri, ec);
  60. con->add_subprotocol("janus-protocol");
  61. if(ec)
  62. {
  63. std::cout << "could not create connection because: " << ec.message() << std::endl;
  64. return 0;
  65. }
  66. auto hdl = con->get_handle();
  67. c.connect(con);
  68. boost::asio::deadline_timer t(c.get_io_service(), boost::posix_time::seconds(5)); //设置一个5s超时的定时器
  69. t.async_wait(bind(&Timeout, &c, hdl, &t, ::_1));
  70. std::thread th([&c] { c.run(); });
  71. //休眠13s后取消定时器并关闭连接
  72. sleep(13);
  73. t.cancel();
  74. c.close(hdl, websocketpp::close::status::normal, "");
  75. th.join();
  76. }

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

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

重复关闭和打开连接

  1. #include <websocketpp/config/asio_no_tls_client.hpp>
  2. #include <websocketpp/client.hpp>
  3. #include <iostream>
  4. typedef websocketpp::client<websocketpp::config::asio_client> client;
  5. using websocketpp::lib::placeholders::_1;
  6. using websocketpp::lib::placeholders::_2;
  7. typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
  8. class connection
  9. {
  10. public:
  11. void on_open(websocketpp::connection_hdl hdl)
  12. {
  13. std::string msg = "hello";
  14. c.send(hdl, msg, websocketpp::frame::opcode::text);
  15. c.get_alog().write(websocketpp::log::alevel::app, "Tx: " + msg);
  16. }
  17. void on_message(websocketpp::connection_hdl hdl, message_ptr msg)
  18. {
  19. std::cout << "on_message called with hdl: " << hdl.lock().get()
  20. << " and message: " << msg->get_payload()
  21. << std::endl;
  22. websocketpp::lib::error_code ec;
  23. if(ec)
  24. {
  25. std::cout << "Echo failed because " << ec.message() << std::endl;
  26. }
  27. }
  28. int init()
  29. {
  30. uri = "ws://xx.xx.xx.xx:xx";
  31. c.set_access_channels(websocketpp::log::alevel::all);
  32. c.clear_access_channels(websocketpp::log::alevel::frame_payload);
  33. c.clear_access_channels(websocketpp::log::alevel::frame_header);
  34. c.init_asio();
  35. c.set_message_handler(websocketpp::lib::bind(&connection::on_message, this,::_1, ::_2));
  36. c.set_open_handler(websocketpp::lib::bind(&connection::on_open, this, _1));
  37. c.start_perpetual();
  38. thread_=websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run,&c);
  39. }
  40. void connect()
  41. {
  42. websocketpp::lib::error_code ec;
  43. client::connection_ptr con = c.get_connection(uri, ec);
  44. if(ec)
  45. {
  46. std::cout << "could not create connection because: " << ec.message() << std::endl;
  47. return ;
  48. }
  49. hdl_ = con->get_handle();
  50. c.connect(con);
  51. }
  52. void close()
  53. {
  54. c.close(hdl_, websocketpp::close::status::normal, "");
  55. }
  56. void terminate()
  57. {
  58. c.stop_perpetual();
  59. thread_->join();
  60. }
  61. private:
  62. client c;
  63. websocketpp::lib::shared_ptr<websocketpp::lib::thread> thread_;
  64. websocketpp::connection_hdl hdl_;
  65. std::string uri;
  66. };

需要重复打开关闭连接时,只调用一次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. dp复习 背包[礼物]

    [问题描述]人生赢家老王在网上认识了一个妹纸,然后妹纸的生日到了,为了表示自己的心意,他决定送她礼物.可是她喜爱的东西特别多,然而他的钱数有限,因此他想知道当他花一定钱数后剩余钱数无法再购买任何一件剩 ...

  2. Pillow模块图片生成

    0825自我总结 Pillow模块图片生成 一.模块安装 pip3 install pillow 二.模块的载入 import PIL 三.django结合img标签生成图片 img.html < ...

  3. 面试官,Java8 JVM内存结构变了,永久代到元空间

    在文章<JVM之内存结构详解>中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化.作为面试官如果你还不知道,那么面试过程中是不是有些露怯? ...

  4. CVE-2019-0708(非蓝屏poc)远程桌面代码执行漏洞复现

    玩了几天 刚回成都  玩电脑复现一下~ 内核漏洞原理暂时 没看懂 别问 ,问就是不懂 0x01 复现环境和Exp准备 漏洞影响范围 Windows 7 Windows Server 2008 R2 W ...

  5. Windows下计划任务的使用

    0x01 前言 在渗透测试中,尤其是域渗透,常常会用到Windows系统的计划任务,一是用于远程启动程序,二是用于程序的自启动 那么,计划任务具体有哪些使用技巧呢?是否对权限有要求?一定需要管理员权限 ...

  6. msf后门之persistence

    在获取得了meterpreter shell后 使用Persistence建立持续性后门 run persistence -h meterpreter > run persistence -h ...

  7. 《疯狂java-突破程序员基本功的16课 》笔记总结

    本人最近读完<疯狂java-突破程序员基本功的16课 >读完后,感觉对java基础又有了新的认识,在这里总结一下:一.数组与内存控制 1.1 数组初始化     java语言的数组是静态的 ...

  8. Ubuntu16.04搭建boost环境

    下载地址:http://sourceforge.net/projects/boost/files/boost/1.58.0/boost_1_58_0.tar.bz2/download 编译前所需的库 ...

  9. RGB颜色值

  10. Markdown进阶(1)

    对于工科生来说,在书写Markdown文本时,免不了要和上下标打交道,网上的博客大多良莠不齐,不太友好,本文想尽可能地解决一些在看完基础教程后再来书写Markdown文本时容易遇到的问题. 1.上下标 ...