title: "WebSocket"
cpp-httplib supports WebSocket as well. Unlike HTTP request/response, WebSocket lets the server and client exchange messages in both directions. It's great for chat apps and real-time notifications.
Let's build an echo server and client right away.
Here's an echo server that sends back whatever message it receives.
#include "httplib.h"
#include <iostream>
int main() {
httplib::Server svr;
svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) {
std::string msg;
while (ws.read(msg)) {
ws.send(msg); // Send back the received message as-is
}
});
std::cout << "Listening on port 8080..." << std::endl;
svr.listen("0.0.0.0", 8080);
}
You register a WebSocket handler with svr.WebSocket(). It works just like svr.Get() and svr.Post() from Chapter 3.
Inside the handler, ws.read(msg) waits for a message. When the connection closes, read() returns false, so the loop exits. ws.send(msg) sends a message back.
Let's connect to the server using httplib::ws::WebSocketClient.
#include "httplib.h"
#include <iostream>
int main() {
httplib::ws::WebSocketClient client("ws://localhost:8080/ws");
if (!client.connect()) {
std::cout << "Connection failed" << std::endl;
return 1;
}
// Send a message
client.send("Hello, WebSocket!");
// Receive a response from the server
std::string msg;
if (client.read(msg)) {
std::cout << msg << std::endl; // Hello, WebSocket!
}
client.close();
}
Pass a URL in ws://host:port/path format to the constructor. Call connect() to start the connection, then use send() and read() to exchange messages.
WebSocket has two types of messages: text and binary. You can tell them apart by the return value of read().
svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) {
std::string msg;
httplib::ws::ReadResult ret;
while ((ret = ws.read(msg))) {
if (ret == httplib::ws::Binary) {
ws.send(msg.data(), msg.size()); // Send as binary
} else {
ws.send(msg); // Send as text
}
}
});
ws.send(const std::string &) — sends as a text messagews.send(const char *, size_t) — sends as a binary messageThe client-side API is the same.
You can read HTTP request information from the handshake through the first argument req in the handler. This is handy for checking authentication tokens.
svr.WebSocket("/ws", [](const httplib::Request &req, httplib::ws::WebSocket &ws) {
auto token = req.get_header_value("Authorization");
if (token.empty()) {
ws.close(httplib::ws::CloseStatus::PolicyViolation, "unauthorized");
return;
}
std::string msg;
while (ws.read(msg)) {
ws.send(msg);
}
});
WebSocket over HTTPS (WSS) is also supported. On the server side, just register a WebSocket handler on httplib::SSLServer.
httplib::SSLServer svr("cert.pem", "key.pem");
svr.WebSocket("/ws", [](const httplib::Request &, httplib::ws::WebSocket &ws) {
std::string msg;
while (ws.read(msg)) {
ws.send(msg);
}
});
svr.listen("0.0.0.0", 8443);
On the client side, use the wss:// scheme.
httplib::ws::WebSocketClient client("wss://localhost:8443/ws");
Now you know the basics of WebSocket. This wraps up the Tour.
The next page gives you a summary of features we didn't cover in the Tour.
Next: What's Next