title: C or C++ websocket client working example
body: <p>I am new to C and C++. I am trying to find small working example for any websocket library in C or C++ that can connect to websocket server. So, far I have explored, uWebsockets, libwebsockets, websocketpp, and boost::beast. None of them seem to have detailed documentation. I found some examples on boost::beast website at <a href="https://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/examples.html" rel="nofollow noreferrer">https://www.boost.org/doc/libs/develop/libs/beast/doc/html/beast/examples.html</a>, however they are not working either. If I can find make a single working example I can work on it to learn more.</p>
  <p>I tried this command, and it is connecting to yahoo endpoint:
  wscat -c &quot;wss://streamer.finance.yahoo.com/&quot; -H 'Origin: https://finance.yahoo.com'
  and print a random string.</p>
  <pre><code>wscat -c &quot;wss://streamer.finance.yahoo.com/&quot; -H 'Origin: https://finance.yahoo.com'
  Connected (press CTRL+C to quit)
  &gt; {&quot;subscribe&quot;:[&quot;ES=F&quot;,&quot;YM=F&quot;,&quot;NQ=F&quot;,&quot;RTY=F&quot;,&quot;CL=F&quot;,&quot;GC=F&quot;,&quot;SI=F&quot;,&quot;EURUSD=X&quot;,&quot;^TNX&quot;,&quot;^VIX&quot;,&quot;GBPUSD=X&quot;,&quot;JPY=X&quot;,&quot;BTC-USD&quot;,&quot;^CMC200&quot;,&quot;^FTSE&quot;,&quot;^N225&quot;,&quot;INTC&quot;]}
  &lt; CgdCVEMtVVNEFduJQ0cYoP2/2/VeIgNVU0QqA0NDQzApOAFFlmEuP0iAgL/AwQJVlwxHR139ST1HZYBWqUNqC0JpdGNvaW4gVVNEsAGAgL/AwQLYAQTgAYCAv8DBAugBgIC/wMEC8gEDQlRD+gENQ29pbk1hcmtldENhcIECAAAAADbvcUGJAgAAhAG9ZWtC
  &lt; CgdCVEMtVVNEFQTtQkcY4KbH2/VeIgNVU0QqA0NDQzApOAFFUznHPkiAgMzPwQJVlwxHR139ST1HZQBrQUNqC0JpdGNvaW4gVVNEsAGAgMzPwQLYAQTgAYCAzM/BAugBgIDMz8EC8gEDQlRD+gENQ29pbk1hcmtldENhcIECAAAAADbvcUGJAgAAND7DT2tC
  </code></pre>
  <p>I tried simple python code like this</p>
  <pre><code>from websocket import create_connection
  import json
  import pprint
  import re
  import time
  import datetime
  
  
  
  def subscribe_yahoo ():        
      headers = {
          'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0',
          'Accept': '*/*',
          'Accept-Language': 'en-US,en;q=0.5',
          'Sec-WebSocket-Version': '13',
          'Origin': 'https://finance.yahoo.com',
          'Sec-WebSocket-Key': 'nNtGm/0ZJcrR+goawlJz9w==',
          'DNT': '1',
          'Connection': 'keep-alive, Upgrade',
          'Sec-Fetch-Dest': 'websocket',
          'Sec-Fetch-Mode': 'websocket' ,
          'Sec-Fetch-Site': 'same-site' ,
          'Pragma': 'no-cache',
          'Cache-Control': 'no-cache',
          'Upgrade': 'websocket',
      }
  
  
      messages='{&quot;subscribe&quot;:[&quot;INTC&quot;]}'
  
      # Initialize the headers needed for the websocket connection
      initMessages = [
         messages,
         
      ]
  
  
      
      websocketUri = &quot;&quot;&quot;wss://streamer.finance.yahoo.com/&quot;&quot;&quot;
      print (websocketUri)
             
      ws = create_connection(websocketUri,header=headers)
      for m in initMessages:
          print (&quot;sending &quot;, m)
          ws.send(m)
              
      message_stream = True
      i=0
      while message_stream:
          result = ws.recv()
          i=i+1
          print (str(i),' -- ', result)
  
  
  subscribe_yahoo()
  </code></pre>
  <p>and it is working too.</p>
  <p>I would really appreciate if someone can help me with a code that works similarly in c or c++.</p>
  <p>Can someone explain if it is possible to use firefox source code <a href="https://searchfox.org/mozilla-central/source/netwerk/protocol/websocket" rel="nofollow noreferrer">https://searchfox.org/mozilla-central/source/netwerk/protocol/websocket</a>  to implement a websocket client in C++ or not, or if someone has used firefox code successfully for websocket client.</p>
  <p>I haven't asked for any recommended library, any library will do for my learning purpose.
  Thanks in advance :)</p>
  <p>Following example is copied as is from <a href="https://www.boost.org/doc/libs/develop/libs/beast/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp" rel="nofollow noreferrer">https://www.boost.org/doc/libs/develop/libs/beast/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp</a></p>
  <pre><code>#include &quot;example/common/root_certificates.hpp&quot;
  
  #include &lt;boost/beast/core.hpp&gt;
  #include &lt;boost/beast/ssl.hpp&gt;
  #include &lt;boost/beast/websocket.hpp&gt;
  #include &lt;boost/beast/websocket/ssl.hpp&gt;
  #include &lt;boost/asio/connect.hpp&gt;
  #include &lt;boost/asio/ip/tcp.hpp&gt;
  #include &lt;boost/asio/ssl/stream.hpp&gt;
  #include &lt;cstdlib&gt;
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  
  namespace beast = boost::beast;         // from &lt;boost/beast.hpp&gt;
  namespace http = beast::http;           // from &lt;boost/beast/http.hpp&gt;
  namespace websocket = beast::websocket; // from &lt;boost/beast/websocket.hpp&gt;
  namespace net = boost::asio;            // from &lt;boost/asio.hpp&gt;
  namespace ssl = boost::asio::ssl;       // from &lt;boost/asio/ssl.hpp&gt;
  using tcp = boost::asio::ip::tcp;       // from &lt;boost/asio/ip/tcp.hpp&gt;
  
  // Sends a WebSocket message and prints the response
  int main(int argc, char** argv)
  {
      try
      {
          // Check command line arguments.
          if(argc != 4)
          {
              std::cerr &lt;&lt;
                  &quot;Usage: websocket-client-sync-ssl &lt;host&gt; &lt;port&gt; &lt;text&gt;\n&quot; &lt;&lt;
                  &quot;Example:\n&quot; &lt;&lt;
                  &quot;    websocket-client-sync-ssl echo.websocket.org 443 \&quot;Hello, world!\&quot;\n&quot;;
              return EXIT_FAILURE;
          }
          std::string host = argv[1];
          auto const  port = argv[2];
          auto const  text = argv[3];
  
          // The io_context is required for all I/O
          net::io_context ioc;
  
          // The SSL context is required, and holds certificates
          ssl::context ctx{ssl::context::tlsv12_client};
  
          // This holds the root certificate used for verification
          load_root_certificates(ctx);
  
          // These objects perform our I/O
          tcp::resolver resolver{ioc};
          websocket::stream&lt;beast::ssl_stream&lt;tcp::socket&gt;&gt; ws{ioc, ctx};
  
          // Look up the domain name
          auto const results = resolver.resolve(host, port);
  
          // Make the connection on the IP address we get from a lookup
          auto ep = net::connect(get_lowest_layer(ws), results);
  
          // Set SNI Hostname (many hosts need this to handshake successfully)
          if(! SSL_set_tlsext_host_name(ws.next_layer().native_handle(), host.c_str()))
              throw beast::system_error(
                  beast::error_code(
                      static_cast&lt;int&gt;(::ERR_get_error()),
                      net::error::get_ssl_category()),
                  &quot;Failed to set SNI Hostname&quot;);
  
          // Update the host_ string. This will provide the value of the
          // Host HTTP header during the WebSocket handshake.
          // See https://tools.ietf.org/html/rfc7230#section-5.4
          host += ':' + std::to_string(ep.port());
  
          // Perform the SSL handshake
          ws.next_layer().handshake(ssl::stream_base::client);
  
          // Set a decorator to change the User-Agent of the handshake
          ws.set_option(websocket::stream_base::decorator(
              [](websocket::request_type&amp; req)
              {
                  req.set(http::field::user_agent,
                      std::string(BOOST_BEAST_VERSION_STRING) +
                          &quot; websocket-client-coro&quot;);
              }));
  
          // Perform the websocket handshake
          ws.handshake(host, &quot;/&quot;);
  
          // Send the message
          ws.write(net::buffer(std::string(text)));
  
          // This buffer will hold the incoming message
          beast::flat_buffer buffer;
  
          // Read a message into our buffer
          ws.read(buffer);
  
          // Close the WebSocket connection
          ws.close(websocket::close_code::normal);
  
          // If we get here then the connection is closed gracefully
  
          // The make_printable() function helps print a ConstBufferSequence
          std::cout &lt;&lt; beast::make_printable(buffer.data()) &lt;&lt; std::endl;
      }
      catch(std::exception const&amp; e)
      {
          std::cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; e.what() &lt;&lt; std::endl;
          return EXIT_FAILURE;
      }
      return EXIT_SUCCESS;
  }
  
  </code></pre>
  <p>Compiled using :</p>
  <pre class="lang-none prettyprint-override"><code>g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
  
  g++ boost_test.cpp -o websocket-client-sync-ssl -lboost_system -pthread -lssl -lcrypto
  
  ./websocket-client-sync-ssl
  Usage: websocket-client-sync-ssl &lt;host&gt; &lt;port&gt; &lt;text&gt;
  Example:
      websocket-client-sync-ssl echo.websocket.org 443 &quot;Hello, world!&quot;
  </code></pre>
  <p>then as suggested:</p>
  <pre class="lang-none prettyprint-override"><code>./websocket-client-sync-ssl echo.websocket.org 443 &quot;Hello, world!&quot;
  </code></pre>
  <p>doesn't work</p>
  <pre class="lang-none prettyprint-override"><code>/websocket-client-sync-ssl streamer.finance.yahoo.com 443 &quot;Hello, world!&quot;
  Error: The WebSocket stream was gracefully closed at both endpoints
  </code></pre>