A high-performance C++ HTTP/WebSocket client library built on Boost.Beast with full SSL/TLS support. Designed for asynchronous, non-blocking HTTP/WebSocket communication in modern C++ applications.
- HTTP/HTTPS Client: Full support for GET, POST, PUT, PATCH, and DELETE methods
- HTTP Streaming: Support for Server-Sent Events (SSE) and chunked response streaming
- Asynchronous WebSocket Client: Built on Boost.Asio coroutines for high-performance async operations
- SSL/TLS Support: Native support for secure
https://andwss://connections - Synchronous & Asynchronous APIs: Both blocking and non-blocking HTTP operations
- Cross-Platform: Works on Windows, Linux, and macOS
- Header-Only: Easy integration with minimal dependencies
- Callback-Based API: Clean event-driven interface for connection lifecycle management
- Thread-Safe: Proper strand management for concurrent operations
- Modern C++20: Leverages coroutines and modern C++ features
- Boost (1.75+): beast, asio, context components
- OpenSSL: For SSL/TLS support
- C++20 Compiler: Required for coroutine support
Add slick_net as a subdirectory in your CMake project:
add_subdirectory(path/to/slick_net)
target_link_libraries(your_target PRIVATE slick_net)Or use FetchContent:
include(FetchContent)
FetchContent_Declare(
slick_net
GIT_REPOSITORY https://github.com/SlickQuant/slick_net.git
GIT_TAG main
)
FetchContent_MakeAvailable(slick_net)
target_link_libraries(your_target PRIVATE slick_net)#include <slick/net/websocket.h>
#include <memory>
using namespace slick::net;
int main() {
auto ws = std::make_shared<Websocket>(
"wss://ws.postman-echo.com/raw", // WebSocket URL
[]() { // onConnected
std::cout << "Connected!\n";
},
[]() { // onDisconnected
std::cout << "Disconnected!\n";
},
[](const char* data, size_t size) { // onData
std::cout << "Received: " << std::string(data, size) << "\n";
},
[](std::string err) { // onError
std::cerr << "Error: " << err << "\n";
}
);
ws->open();
// Send a message
std::string message = "Hello, WebSocket!";
ws->send(message.data(), message.size());
// Keep the application running
while(Websocket::is_running()) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}#include <slick/net/websocket.h>
#include <nlohmann/json.hpp>
#include <memory>
using namespace slick::net;
using json = nlohmann::json;
int main() {
std::shared_ptr<Websocket> ws;
ws = std::make_shared<Websocket>(
"wss://advanced-trade-ws.coinbase.com",
[&]() {
std::cout << "Connected to Coinbase\n";
// Subscribe to market data
json subscribe_msg = {
{"type", "subscribe"},
{"channel", "level2"},
{"product_ids", {"BTC-USD"}}
};
auto msg_str = subscribe_msg.dump();
ws->send(msg_str.data(), msg_str.size());
},
[]() {
std::cout << "Disconnected from Coinbase\n";
},
[](const char* data, size_t size) {
std::cout << "Market data: " << std::string(data, size) << "\n";
},
[](std::string err) {
std::cerr << "Error: " << err << "\n";
}
);
ws->open();
// Ctrl + C to exit
// Keep running
while(Websocket::is_running()) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return 0;
}The repository includes working examples. To build them:
mkdir build
cd build
cmake ..
cmake --build .Run examples:
./examples/websocket_client_example
./examples/http_client_example
./examples/http_stream_client_exampleSynchronous Methods:
Http::Response get(std::string_view url, std::vector<std::pair<std::string, std::string>>&& headers = {});
Http::Response post(std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
Http::Response put(std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
Http::Response patch(std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
Http::Response del(std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});Asynchronous Methods:
void async_get(std::function<void(Response&&)> on_response, std::string_view url, std::vector<std::pair<std::string, std::string>>&& headers = {});
void async_post(std::function<void(Response&&)> on_response, std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
void async_put(std::function<void(Response&&)> on_response, std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
void async_patch(std::function<void(Response&&)> on_response, std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});
void async_del(std::function<void(Response&&)> on_response, std::string_view url, std::string_view data, std::vector<std::pair<std::string, std::string>>&& headers = {});Response Structure:
struct Response {
uint32_t result_code; // HTTP status code
std::string result_text; // Response body or error message
bool is_ok() const; // Returns true if status code is 2xx
};Example Usage:
#include <slick/net/http.h>
// Synchronous GET
auto response = Http::get("https://api.example.com/data");
if (response.is_ok()) {
std::cout << response.result_text << std::endl;
}
// Asynchronous POST with JSON
nlohmann::json data = {{"key", "value"}};
Http::async_post([](Http::Response&& rsp) {
if (rsp.is_ok()) {
std::cout << "Success: " << rsp.result_text << std::endl;
}
}, "https://api.example.com/resource", data.dump(), {{"Content-Type", "application/json"}});Constructor:
Websocket(
std::string url,
std::function<void()> onConnected,
std::function<void()> onDisconnected,
std::function<void(const char*, std::size_t)> onData,
std::function<void(std::string)> onError
)Methods:
void open()- Start the WebSocket connectionvoid close()- Close the WebSocket connectionvoid send(const char* buffer, size_t len)- Send data through the WebSocketStatus status() const- Get current connection statusstatic void shutdown()- Shutdown all WebSocket services
Status Enum:
CONNECTING- Connection in progressCONNECTED- Connected and readyDISCONNECTING- Disconnection in progressDISCONNECTED- Disconnected
The HttpStream class provides support for HTTP streaming, including Server-Sent Events (SSE) and chunked responses.
Constructor:
HttpStream(
std::string url,
std::function<void()> onConnected,
std::function<void()> onDisconnected,
std::function<void(const char*, std::size_t)> onData,
std::function<void(std::string)> onError,
std::vector<std::pair<std::string, std::string>>&& headers = {}
)Methods:
void open()- Start the HTTP stream connectionvoid close()- Close the stream connectionStatus status() const- Get current connection statusstatic bool is_running()- Check if any streams are runningstatic void shutdown()- Shutdown all HTTP stream services
Status Enum:
CONNECTING- Connection in progressCONNECTED- Connected and receiving dataDISCONNECTED- Disconnected
Example Usage - Server-Sent Events (SSE):
#include <slick/net/http.h>
auto stream = std::make_shared<HttpStream>(
"https://api.example.com/events",
[]() {
std::cout << "Stream connected\n";
},
[]() {
std::cout << "Stream disconnected\n";
},
[](const char* data, size_t size) {
std::string event(data, size);
std::cout << "Event: " << event << "\n";
},
[](std::string err) {
std::cerr << "Error: " << err << "\n";
}
);
stream->open();
// Stream will receive events via the onData callback
// Close when done
stream->close();Example Usage - OpenAI Streaming API:
#include <slick/net/http.h>
#include <nlohmann/json.hpp>
auto stream = std::make_shared<HttpStream>(
"https://api.openai.com/v1/chat/completions",
[]() {
std::cout << "Connected to OpenAI\n";
},
[]() {
std::cout << "Stream ended\n";
},
[](const char* data, size_t size) {
// Parse streaming JSON chunks
std::string chunk(data, size);
try {
auto json = nlohmann::json::parse(chunk);
if (json.contains("choices")) {
auto delta = json["choices"][0]["delta"];
if (delta.contains("content")) {
std::cout << delta["content"].get<std::string>();
}
}
} catch (...) {}
},
[](std::string err) {
std::cerr << "Error: " << err << "\n";
},
{
{"Authorization", "Bearer YOUR_API_KEY"},
{"Content-Type", "application/json"}
}
);
stream->open();This project is licensed under the MIT License - see the LICENSE file for details.
Part of the SlickQuant ecosystem.
Made with ⚡ by SlickQuant