自学内容网 自学内容网

websocketpp服务器搭建

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


前言

概念:是一个应用层的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();

原文地址:https://blog.csdn.net/2301_77412625/article/details/142311510

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!