boost库websocket客户端

boost库websocket客户端

基于boost标准C++库,使用协程和beast实现websocket客户端。需要连接多少个websocket服务器协议地址,则创建多少个协程以及相应的处理函数即可。

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/spawn.hpp>
#include <cstdlib>
#include <functional>
#include <semaphore.h>
#include <iostream>
#include <string>


namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>


/* 报告错误信息
static void fail(beast::error_code ec, char const* what)
{
	std::cerr << what << ": " << ec.message() << "\n";
}
*/

// prints the response
void do_session1(
	std::string host,
	std::string const& port,
	std::string const& uri,
	net::io_context& ioc,
	net::yield_context yield)
{
    beast::error_code ec;

    while(1)
    {
      	std::string  strHost = host;
   		std::string  strPort = port;
		tcp::resolver resolver(ioc);
    	websocket::stream<beast::tcp_stream> ws(ioc);
		
		beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));

		auto const results = resolver.async_resolve(strHost, strPort, yield[ec]);
	 	auto ep = beast::get_lowest_layer(ws).async_connect(results, yield[ec]);
		if (ec) {
            fail(ec, "async_connect");
			continue;
		}
		strHost += ':' + std::to_string(ep.port());

		// Turn off the timeout on the tcp_stream, because
		// the websocket stream has its own timeout system.
		beast::get_lowest_layer(ws).expires_never();

		// Set suggested timeout settings for the websocket
		    ws.set_option(websocket::stream_base::timeout::suggested(beast::role_type::client));
		ws.async_handshake(strHost, uri, yield[ec]);
		if (ec){
            fail(ec, "async_handshake");
			ws.close(websocket::close_code::normal);
			continue;
	    }
	   
    	while(1)	
    	{
			beast::flat_buffer buffer;

			ws.async_read(buffer, yield[ec]);
			if (ec) {
                fail(ec, "async_read");
				ws.close(websocket::close_code::normal);
				break;
			}
			std::cout << std::string(beast::buffers_to_string(buffer.data()))) << std::endl;
			buffer.clear(); 
	   	}
    }
} 


void do_session2(
	std::string host,
	std::string const& port,
	std::string const& uri,
	net::io_context& ioc,
	net::yield_context yield)
{
    beast::error_code ec;

    while(1)
    {
      	std::string  strHost = host;
   		std::string  strPort = port;
		tcp::resolver resolver(ioc);
    	websocket::stream<beast::tcp_stream> ws(ioc);
		
		beast::get_lowest_layer(ws).expires_after(std::chrono::seconds(30));
		auto const results = resolver.async_resolve(strHost, strPort, yield[ec]);
	 	auto ep = beast::get_lowest_layer(ws).async_connect(results, yield[ec]);
		if (ec) {
            fail(ec, "async_connect");
			continue;
		}
		strHost += ':' + std::to_string(ep.port());

		// Turn off the timeout on the tcp_stream, because
		// the websocket stream has its own timeout system.
		beast::get_lowest_layer(ws).expires_never();

		// Set suggested timeout settings for the websocket
		    ws.set_option(websocket::stream_base::timeout::suggested(beast::role_type::client));
		ws.async_handshake(strHost, uri, yield[ec]);
		if (ec){
            fail(ec, "async_handshake");
			ws.close(websocket::close_code::normal);
			continue;
	    }
	   
    	while(1)	
    	{
			beast::flat_buffer buffer;
            // 需要添加ping及pong机制,这里暂不添加
			ws.async_read(buffer, yield[ec]);
			if (ec) {
                fail(ec, "async_read");
				ws.close(websocket::close_code::normal);
				break;
			}
			std::cout << std::string(beast::buffers_to_string(buffer.data()))) << std::endl;
			buffer.clear(); 
	   	}
    }
} 

int main(void)
{

	auto const host = "192.168.1.111";
    auto const port = "9000";

    try {
		net::io_context ioc;
		
        // 需要几个连接,创建对应个协程数量
		boost::asio::spawn(ioc, std::bind(
			&do_session1,
			std::string(host),
			std::string(port),
			std::string("/aa/gagaga"),
			std::ref(ioc),
			std::placeholders::_1));

		boost::asio::spawn(ioc, std::bind(
			&do_session2,
			std::string(host),
			std::string(port),
			std::string("/aa/lalala"),
			std::ref(ioc),
			std::placeholders::_1));

		// Run the I/O service. The call will return when the socket is closed.
		ioc.run();
    } catch (std::exception const & e) {
        std::cout << "error:" << e.what() << std::endl;
    }

    return NULL;
}

编译:

$:g++ -g -std=gnu++11 -o server websocket_client_coro.cpp -I/websocket/boost_1_73_0/  -L/websocket/boost_1_73_0/stage/lib  -lboost_context -lboost_coroutine -lboost_chrono -lpthread

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值