Location>code7788 >text

Use with concatenation-based connections ws

Popularity:593 ℃/2024-11-10 17:06:33

catalogs

  • catalogs
  • preamble
  • preliminary
  • realization
    • Initialize io_context and listen for signals
    • Start the thread connecting to ws and start io_context
    • Establish a tcp link (the following steps are all in the ws function)
    • ws handshake
    • transmission data
    • effect
  • summarize

preamble

This article focuses on a method to connect to Websocket(ws) using and based on concatenation. The C++ version is 20 and Boost version is 1.82.

preliminary

First a minimal ws server needs to be constructed for testing.
This article constructs a simple ws server using nodejs, based on the ws library.

const WebSocket = require('ws');

const wss = new ({ port: 8080 });

('connection', function connection(ws) {
  ('New client connected')
  ('message', function incoming(message) {
    ('received: %s', message);
    (message);
  });
});

('WebSocket server is running on port 8080');

realization

Initialize io_context and listen for signals

boost::asio::io_context io_context;
boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
signals.async_wait([&](auto, auto){ io_context.stop(); });

Start the thread connecting to ws and start io_context

boost::asio::co_spawn(io_context, ws, boost::asio::detached);
io_context.run();

included among thesewsThe signature of theboost::asio::awaitable<void> ws()

Establish a tcp link (the following steps are all in the ws function)

This step can be divided into two steps, resolving the dns and establishing the tcp link.

auto executor = co_await boost::asio::this_coro::executor;
boost::asio::ip::tcp::socket socket(executor);
boost::asio::ip::tcp::resolver resolver(executor);

// If you don't use thednsanalyze,You can also just use the following direct substitution
// boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8080)
auto point = co_await resolver.async_resolve("localhost", "8080", boost::asio::use_awaitable);

co_await socket.async_connect(
  point->endpoint(),
  boost::asio::use_awaitable);

ws handshake

prior useboost::beast::websocket::stream<boost::asio::ip::tcp::socket&>Packing and then handshaking.

boost::beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(socket);
co_await ws.async_handshake("127.0.0.1", "/", boost::asio::use_awaitable);

The information sent during the handshake is similar to the

GET / HTTP/1.1
Host: 
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
Sec-WebSocket-Version: 13
User-Agent: /216

transmission data

boost::asio::steady_timer timer(executor);
for (;;) {
  co_await ws.async_write(boost::asio::buffer("hello"), boost::asio::use_awaitable);
  std::cout << "send: hello" << std::endl;
  
  boost::beast::flat_buffer buffer;
  co_await ws.async_read(buffer, boost::asio::use_awaitable);
  std::cout << boost::format("recv: %s") % std::string((char *)().data(), ().size()) << std::endl;
  
  timer.expires_after(std::chrono::seconds(1));
  co_await timer.async_wait(boost::asio::use_awaitable);
}

effect

效果图

summarize

With concatenation, boost feels so much better!