当前位置: 首页 > article >正文

websocketpp服务器搭建

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、接口认识
  • 二、搭建websocketpp服务器
    • 0.重定义server类型
    • 1.实例化服务器对象
    • 2.初始化日志输出
    • 3.初始化asio框架
    • 4.设置回调函数
    • 5.设置地址重用,设置监听端口,开始监听
    • 6.启动服务器


前言

概念:是一个应用层的tcp长连接协议。
搭建一个websocket服务器其实就是搭建了一个tcp服务器,只不过应用层使用websocket协议
格式进行数据处理。
在IM项目中:
客户端 -----HTTP----- 服务器
但是在聊天室项目中,不单单是请求-响应的业务处理,还包含了数据的主动推送
而这种消息数据的主动推送,是HTTP协议无法实现的。
因此需要搭建一个长连接的服务器,用于主动向客户端推送数据。
选择websocket协议的考虑:因为HTTP通信支持websocket协议的切换

websocketpp底层网络通信是依靠的boost中的asio异步机制实现的.


一、接口认识

有一个endpoint类,这个类中提供了一些接口,包括设置四种回调函数,设置日志打印等级,
还有获取connection_hdl对应的连接。初始化asio框架,启动地址服用,设置监听端口,启动故服务器。

namespace websocketpp {
typedef lib::weak_ptr<void> connection_hdl;
template <typename config>
class endpoint : public config::socket_type {

typedef typename connection_type::ptr connection_ptr;
typedef typename connection_type::message_ptr message_ptr;

typedef lib::function<void(connection_hdl)> open_handler;
typedef lib::function<void(connection_hdl)> close_handler;
typedef lib::function<void(connection_hdl)> http_handler;
typedef lib::function<void(connection_hdl,message_ptr)> message_handler;

/* websocketpp::log::alevel::none 禁止打印所有日志*/
void set_access_channels(log::level channels);/*设置日志打印等级*/

/*设置指定事件的回调函数*/
void set_open_handler(open_handler h);/*websocket 握手成功
回调处理函数*/
void set_close_handler(close_handler h);/*websocket 连接关
闭回调处理函数*/
void set_message_handler(message_handler h);/*websocket 消
息回调处理函数*/
void set_http_handler(http_handler h);/*http 请求回调处理函数*/

/*获取 connection_hdl 对应连接的 connection_ptr*/
connection_ptr get_con_from_hdl(connection_hdl hdl);
/*websocketpp 基于 asio 框架实现,init_asio 用于初始化 asio 框架中的 io_service 调度器*/
void init_asio();

/*设置是否启用地址重用*/
void set_reuse_addr(bool value);

/*设置 endpoint 的绑定监听端口*/
void listen(uint16_t port);

};

还有一个server类,这个类继承了endpoint类,也就拥有了上面的函数,所以我们搭建服务器主要是使用Server类。

class server : public endpoint<connection<config>,config> {
/*初始化并启动服务端监听连接的 accept 事件处理*/
void start_accept();
}

二、搭建websocketpp服务器

0.重定义server类型

因为server类是带有模板参数的,类型很长,这里我们typedef以下,方便我们使用

typedef websocketpp::server<websocketpp::config::asio> server_t;

1.实例化服务器对象

创建一个server对象

server_t server;

2.初始化日志输出

关闭websocketpp的日志输出

server.set_access_channels(websocketpp::log::alevel::none);

3.初始化asio框架

前面也说了,websocketpp底层网络通信是依靠boost的asio异步通信机制实现的。

server.init_asio();

4.设置回调函数

这里有一个需要介绍的是,消息处理回调函数的设置,我们使用了bind,绑定了server对象进去。因为在消息处理回调函数中我们需要使用server对象获取到连接,使用连接来对数据进行响应。

	server.set_open_handler(onOpen);
    server.set_close_handler(onClose);
    
    auto msg_hadler = std::bind(onMessage, &server, std::placeholders::_1, std::placeholders::_2);
    server.set_message_handler(msg_hadler);

这里是设置的回调函数,这里的形参websocketpp::connection_hdl hdl它是一个weak_ptr,我们需要使用server中的一个函数get_con_from_hdl来获取到connection_ptr对象,这是一个shared_ptr,在这个对象里面有一个函数send可以进行响应发送。

可以看到,send需要填写两个参数,一个是响应正文,还有一个则是响应真正文的类型,我们这里填写的是文本类型,在项目中我们使用protobuf对正文进行序列化,因此需要使用binary类型。

还有一个需要介绍的是我们需要使用message_ptr中的get_payload()函数获取消息正文。

void onOpen(websocketpp::connection_hdl hdl) {
    std::cout << "websocket长连接建立成功!\n";
}
void onClose(websocketpp::connection_hdl hdl) {
    std::cout << "websocket长连接断开!\n";
    
}
void onMessage(server_t *server, websocketpp::connection_hdl hdl, server_t::message_ptr msg) {
    //1. 获取有效消息载荷数据,进行业务处理
    std::string body = msg->get_payload();
    std::cout << "收到消息:" << body << std::endl;
    //2. 对客户端进行响应
    //获取通信连接
    auto conn = server->get_con_from_hdl(hdl);
    //发送数据
    conn->send(body + "-Hello!", websocketpp::frame::opcode::value::text);
}

5.设置地址重用,设置监听端口,开始监听

websocketpp不想httplib,设置监听后并没有开启监听,还需要手动开启监听。

//    5. 启用地址重用
    server.set_reuse_addr(true);
    //    5. 设置监听端口
    server.listen(9090);
    //    6. 开始监听
    server.start_accept();

6.启动服务器

server.run();

http://www.kler.cn/news/312461.html

相关文章:

  • 使用knn算法对iris数据集进行分类
  • 人力资源数据集分析(一)_t-test、卡方检验和描述性统计
  • Spring Cloud常见面试题
  • 电子电气架构---智能汽车应该是怎么样的架构?
  • 24.9.18学习笔记
  • opengl-redbook环境搭建(静态库)
  • 『功能项目』事件中心处理怪物死亡【55】
  • Vue3:props实现组件通信
  • react 创建react项目
  • 高级java每日一道面试题-2024年9月14日-基础篇-如何处理事务中的性能问题?
  • 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线
  • Bio-Linux-shell详解-1-从0开始
  • 【Ubuntu】虚拟机安装USB摄像头ROS驱动 usb_cam(最新方法)
  • ES5 在 Web 上的现状
  • [ffmpeg] packet
  • element-plus的菜单组件el-menu
  • 7--SpringBoot-后端开发、原理详解(面试高频提问点)
  • Web开发:ABP框架3——入门级别的接口增删改查实现原理
  • 基于SpringBoot的自习室预订系统
  • 莱卡相机sd内存卡格式化了怎么恢复数据
  • Volta无障碍的 JavaScript 工具管理器
  • Java 中使用 Redis 的几种方式优缺点对比
  • Linux 生成 git ssh 公钥
  • 站群服务器适用于哪些场景当中?
  • Linux服务器及应用环境快速部署、调试、迁移、维护、监控
  • Jenkins怎么设置每日自动执行构建任务?
  • 使用 nvm 管理 node 版本:如何在 macOS 和 Windows 上安装使用nvm
  • UniApp如何打包成客户端应用程序
  • 前后端分离集成CAS单点登录
  • Windows安装HeidiSQL教程(图文)