Websocketpp简单HTTP客户端

Websocketpp simple HTTP client

本文关键字:客户端 HTTP 简单 Websocketpp      更新时间:2023-10-16

我使用出色的websockettpp库在C++应用程序中提供Websockets(和HTTP)服务器。我还需要同一应用程序中的HTTP客户端来连接到RESTAPI。我也在websockettpp中尝试过,但到目前为止,我几乎没有成功。下面的初步尝试给了我这个日志输出:

[2015-03-06 18:01:18] [connect] Successful connection
[2015-03-06 18:01:18] [error] Server handshake response error: websocketpp.processor:20 (Invalid HTTP status.)
[2015-03-06 18:01:18] [disconnect] Failed: Invalid HTTP status.

这表明我的http_处理程序方法可能需要更多内容。如有任何建议,我们将不胜感激。websockettpp文档和示例似乎不包括一个简单的HTTP客户端。

#define _WEBSOCKETPP_CPP11_STL_
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/common/thread.hpp>
namespace {
using namespace websocketpp;
typedef client<websocketpp::config::asio_client> client;
class Client {
public:
    Client(void){
        client_.init_asio();
        client_.set_http_handler(bind(&Client::http_,this,_1));
    }
    std::string get(const std::string& url) {
        websocketpp::lib::error_code error;
        client::connection_ptr con = client_.get_connection(url,error);
        if(error) std::runtime_error("Unable to connnect.n  url: "+url+"n  message: "+error.message());
        client_.connect(con);
        websocketpp::lib::thread asio_thread(&client::run, &client_);
        asio_thread.join();
        return data_;
    }
private:
    void http_(connection_hdl hdl){
        std::cout<<"Connectedn";
        data_ = "http payload";
    }
    client client_;
    std::string data_;
};
}
int main(void){
    Client client;
    client.get("http://google.com/");
}

WebSocket++的HTTP处理功能是一种方便的功能,旨在允许WebSocket服务器以有限的容量提供HTTP响应。WebSocket++不打算用作通用HTTP库,也不包含扮演(非WebSocket)HTTP客户端角色的功能。

为HTTP客户端功能使用单独的库(如cpp-netlib)是一个很好的解决方案。

如果你想在C++中同时使用WebSocket和HTTP,那么有一个名为Beast的伟大库可以同时使用这两种功能!它是开源的,建立在Boost.Asio之上:https://github.com/vinniefalco/Beast/

下面是一些示例代码:

使用HTTP从网站请求根页面并打印响应:

#include <beast/http.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
    // Normal boost::asio setup
    std::string const host = "boost.org";
    boost::asio::io_service ios;
    boost::asio::ip::tcp::resolver r(ios);
    boost::asio::ip::tcp::socket sock(ios);
    boost::asio::connect(sock,
        r.resolve(boost::asio::ip::tcp::resolver::query{host, "http"}));
    // Send HTTP request using beast
    beast::http::request_v1<beast::http::empty_body> req;
    req.method = "GET";
    req.url = "/";
    req.version = 11;
    req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
    req.headers.replace("User-Agent", "Beast");
    beast::http::prepare(req);
    beast::http::write(sock, req);
    // Receive and print HTTP response using beast
    beast::streambuf sb;
    beast::http::response_v1<beast::http::streambuf_body> resp;
    beast::http::read(sock, sb, resp);
    std::cout << resp;
}

建立WebSocket连接,发送消息并接收回复:

#include <beast/to_string.hpp>
#include <beast/websocket.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>
int main()
{
    // Normal boost::asio setup
    std::string const host = "echo.websocket.org";
    boost::asio::io_service ios;
    boost::asio::ip::tcp::resolver r(ios);
    boost::asio::ip::tcp::socket sock(ios);
    boost::asio::connect(sock,
        r.resolve(boost::asio::ip::tcp::resolver::query{host, "80"}));
    // WebSocket connect and send message using beast
    beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(sock);
    ws.handshake(host, "/");
    ws.write(boost::asio::buffer("Hello, world!"));
    // Receive WebSocket message, print and close using beast
    beast::streambuf sb;
    beast::websocket::opcode op;
    ws.read(op, sb);
    ws.close(beast::websocket::close_code::normal);
    std::cout << to_string(sb.data()) << "n";
}

我不知道如何阻止websocketpp客户端请求Upgrade: connection,所以我最终使用cpp-netlib作为HTTP客户端。