c++ websocket简单讲解

只做简单讲解。

一.定义和原理

        WebSocket 是从 HTML5 开始⽀持的⼀种⽹⻚端和服务端保持⻓连接的消息推送机制,传统的 web 程序都是属于 "⼀问⼀答" 的形式,即客⼾端给服务器发送了⼀个 HTTP 请求,服务器给客⼾端返回⼀个 HTTP 响应。这种情况下服务器是属于被动的⼀⽅,如果客⼾端不主动发起请求服务器就⽆法主动给客⼾端响应。

        WebSocket 更接近于 TCP 这种级别的通信⽅式,⼀旦连接建⽴完成客⼾端或者服务器都可以主动的向对⽅发送数据。WebSocket 协议本质上是⼀个基于 TCP 的协议。为了建⽴⼀个 WebSocket 连接,客⼾端浏览器⾸先 要向服务器发起⼀个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了⼀些附加头信息,通过 这个附加头信息完成握⼿过程并升级协议的过程。

        首先先经过TCP三次握手,然后再通过HTTP协议发送更新协议请求,最终切换为websocket协议进行通信。 

        WebSocketpp同时⽀持HTTP和Websocket两种⽹络协议。

二.搭建服务器简易流程

        由于库里的接口服务器过于复杂,需要的请查看⽤⼾⼿册: http://docs.websocketpp.org/。

重要的接口在下面用到讲解。

int main()
{   //1. 实例化server对象
    wsserver_t wssrv;
    //2. 设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3. 初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);
    //4. 设置回调函数
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));
    wssrv.set_message_handler(std::bind(wsmsg_callback, &wssrv, std::placeholders::_1, 
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));
   std::placeholders::_2));
    //5. 设置监听端口
    wssrv.listen(8085);
    
    //6. 开始获取新连接
    wssrv.start_accept();
    //7. 启动服务器
    wssrv.run();
    return 0;
}

四个回调函数分别为: websocket握⼿成功回调处理函数,http请求回调处理函数,websocket消息回调处理函数,websocket连接关闭回调处理函数。在对应的事件触发后自动调用。

三.简单服务器的搭建

        编写一个简单服务器,对浏览器的请求返回一个简单的http界面。代码如下:

#include <iostream>
#include <string>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

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

void print(const std::string &str)
{
    std::cout << str << std::endl;
}

void http_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    //给客户端返回一个hello world的页面
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << "body: " << conn->get_request_body() << std::endl; 
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>Hello World</h1></body></html>";
    conn->set_body(body);
    conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::ok);
   // wsserver_t::timer_ptr tp = srv->set_timer(5000, std::bind(print, "bitejiuyeke"));
   // tp->cancel();//定时任务的取消,会导致定时任务立即被执行
}
void wsopen_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    std::cout << "websocket握手成功!!\n";
}
void wsclose_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    std::cout << "websocket连接断开!!\n";
}
void wsmsg_callback(wsserver_t *srv, websocketpp::connection_hdl hdl, wsserver_t::message_ptr msg) {
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << "wsmsg: " << msg->get_payload() << std::endl;
    std::string rsp = "client say: " + msg->get_payload();
    conn->send(rsp, websocketpp::frame::opcode::text);
}
int main()
{
    //1. 实例化server对象
    wsserver_t wssrv;
    //2. 设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3. 初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);
    //4. 设置回调函数
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));
    wssrv.set_message_handler(std::bind(wsmsg_callback, &wssrv, std::placeholders::_1, std::placeholders::_2));
    //5. 设置监听端口
    wssrv.listen(8085);
    //6. 开始获取新连接
    wssrv.start_accept();
    //7. 启动服务器
    wssrv.run();
    return 0;
}

        

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值