### HTTP Server Setup and Basic Listening Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Initialize and start an HTTP server on a specified port and hostname. This snippet shows the basic steps to get the server listening for incoming connections. ```cpp #include ix::HttpServer server(port, hostname); auto res = server.listen(); if (!res.first) { std::cerr << res.second << std::endl; return 1; } server.start(); server.wait(); ``` -------------------------------- ### Basic WebSocket Client Setup and Usage Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Set up a WebSocket client, configure its URL, enable optional features like ping intervals and per-message deflate, define a message callback, start the client, send messages, and stop the connection. ```cpp #include ... // Our websocket object ix::WebSocket webSocket; std::string url("ws://localhost:8080/"); webSocket.setUrl(url); // Optional heart beat, sent every 45 seconds when there is not any traffic // to make sure that load balancers do not kill an idle connection. webSocket.setPingInterval(45); // Per message deflate connection is not enabled by default. You can tweak its parameters, enable or disable it with webSocket.enablePerMessageDeflate(); webSocket.disablePerMessageDeflate(); // Setup a callback to be fired when a message or an event (open, close, error) is received webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr& msg) { if (msg->type == ix::WebSocketMessageType::Message) { std::cout << msg->str << std::endl; } } ); // Now that our callback is setup, we can start our background thread and receive messages webSocket.start(); // Send a message to the server (default to TEXT mode) webSocket.send("hello world"); // The message can be sent in BINARY mode (useful if you send MsgPack data for example) webSocket.sendBinary("some serialized binary data"); // ... finally ... // Stop the connection webSocket.stop() ``` -------------------------------- ### WebSocketServer Setup and Usage Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md This snippet demonstrates how to set up a WebSocket server, bind it to a port and host, enable callbacks for new connections and messages, and start the server. ```APIDOC ## WebSocketServer Setup and Usage ### Description This section details the setup and usage of the `WebSocketServer` class, including how to initialize it, set connection and message callbacks, and manage the server lifecycle. ### Method - `WebSocketServer(int port, const std::string& host = "0.0.0.0", const std::string& path = "/")` - `setOnConnectionCallback(std::function, std::shared_ptr)> callback)` - `listen()` - `disablePerMessageDeflate()` - `start()` - `wait()` - `stop()` ### Endpoint N/A (This is an SDK reference, not an HTTP API) ### Parameters #### `WebSocketServer` Constructor Parameters - **port** (int) - Required - The port number to listen on. - **host** (std::string) - Optional - The host address to bind to. Defaults to "0.0.0.0" for accessibility from any machine. - **path** (std::string) - Optional - The WebSocket path. Defaults to "/". #### `setOnConnectionCallback` Parameters - **callback** (std::function) - Required - A function to be called when a new WebSocket connection is established. It receives a `std::weak_ptr` and a `std::shared_ptr`. #### `listen()` Parameters None. #### `disablePerMessageDeflate()` Parameters None. #### `start()` Parameters None. #### `wait()` Parameters None. #### `stop()` Parameters None. ### Request Example ```cpp #include int port = 8008; std::string host("127.0.0.1"); ix::WebSocketServer server(port, host); server.setOnConnectionCallback( [&server](std::weak_ptr webSocket, std::shared_ptr connectionState) { // Connection handling logic here auto ws = webSocket.lock(); if (ws) { ws->setOnMessageCallback( [webSocket, connectionState, &server](const ix::WebSocketMessagePtr msg) { // Message handling logic here } ); } } ); auto res = server.listen(); if (!res.first) { // Error handling return 1; } server.disablePerMessageDeflate(); server.start(); server.wait(); ``` ### Response #### `listen()` Return Value - **res** (std::pair) - A pair where the first element is a boolean indicating success or failure, and the second element is an error message if applicable. #### `ConnectionState` Object - **remoteIp** (std::string) - The IP address of the remote client. - **getId()** (std::string) - Returns the unique identifier for the connection. #### `WebSocketMessagePtr` Object - **type** (ix::WebSocketMessageType) - The type of the message (e.g., Open, Message, Close). - **str** (std::string) - The message content if it's a text message. - **binary** (bool) - True if the message is binary, false otherwise. - **openInfo** (OpenMessageInfo) - Contains information about the connection opening event, including URI and headers. ### Error Handling - The `listen()` method returns a pair indicating success or failure. Check the boolean value for errors. - Exceptions may be thrown during server operations; consider using try-catch blocks. ``` -------------------------------- ### Build and Install with CMake Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Configure, build, and install the library using CMake. This process installs headers and the static library to the target directory. ```bash mkdir build cd build cmake -DUSE_TLS=1 .. make -j make install # will install to /usr/local on Unix, on macOS it is a good idea to sudo chown -R `whoami`:staff /usr/local ``` -------------------------------- ### Install IXWebSocket using vcpkg Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Install the IXWebSocket library using the vcpkg package manager. This command fetches and builds the library. ```bash vcpkg install ixwebsocket ``` -------------------------------- ### Build and Run Docker Server with SSL Source: https://github.com/machinezone/ixwebsocket/blob/master/test/compatibility/python/websockets/README.md Builds the Docker image and starts the websocket server with SSL enabled. Ensure you have Docker installed and configured. ```bash make docker && make server_ssl ``` -------------------------------- ### Simple WebSocket Client Example Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/index.md This C++ code demonstrates a basic standalone WebSocket client. It connects to a specified URL, sets up a message callback to handle incoming messages and connection events, and allows sending messages from the console. Ensure you have the necessary build tools and libraries installed. ```cpp /* * main.cpp * Author: Benjamin Sergeant * Copyright (c) 2020 Machine Zone, Inc. All rights reserved. * * Super simple standalone example. See ws folder, unittest and doc/usage.md for more. * * On macOS * $ mkdir -p build ; (cd build ; cmake -DUSE_TLS=1 .. ; make -j ; make install) * $ clang++ --std=c++11 --stdlib=libc++ main.cpp -lixwebsocket -lz -framework Security -framework Foundation * $ ./a.out * * Or use cmake -DBUILD_DEMO=ON option for other platforms */ #include #include #include #include int main() { // Required on Windows ix::initNetSystem(); // Our websocket object ix::WebSocket webSocket; // Connect to a server with encryption // See https://machinezone.github.io/IXWebSocket/usage/#tls-support-and-configuration std::string url("wss://echo.websocket.org"); webSocket.setUrl(url); std::cout << "Connecting to " << url << "..." << std::endl; // Setup a callback to be fired (in a background thread, watch out for race conditions !) // when a message or an event (open, close, error) is received webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr& msg) { if (msg->type == ix::WebSocketMessageType::Message) { std::cout << "received message: " << msg->str << std::endl; std::cout << "> " << std::flush; } else if (msg->type == ix::WebSocketMessageType::Open) { std::cout << "Connection established" << std::endl; std::cout << "> " << std::flush; } else if (msg->type == ix::WebSocketMessageType::Error) { // Maybe SSL is not configured properly std::cout << "Connection error: " << msg->errorInfo.reason << std::endl; std::cout << "> " << std::flush; } } ); // Now that our callback is setup, we can start our background thread and receive messages webSocket.start(); // Send a message to the server (default to TEXT mode) webSocket.send("hello world"); // Display a prompt std::cout << "> " << std::flush; std::string text; // Read text from the console and send messages in text mode. // Exit with Ctrl-D on Unix or Ctrl-Z on Windows. while (std::getline(std::cin, text)) { webSocket.send(text); std::cout << "> " << std::flush; } return 0; } ``` -------------------------------- ### WebSocket Server Setup and Configuration Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Initialize and run a WebSocket server, including setting connection callbacks and message handlers. Supports custom connection states and per-message deflate configuration. ```cpp #include ... // Run a server on localhost at a given port. // Bound host name, max connections and listen backlog can also be passed in as parameters. int port = 8008; std::string host("127.0.0.1"); // If you need this server to be accessible on a different machine, use "0.0.0.0" ix::WebSocketServer server(port, host); server.setOnConnectionCallback( [&server](std::weak_ptr webSocket, std::shared_ptr connectionState) { std::cout << "Remote ip: " << connectionState->remoteIp << std::endl; auto ws = webSocket.lock(); if (ws) { ws->setOnMessageCallback( [webSocket, connectionState, &server](const ix::WebSocketMessagePtr msg) { if (msg->type == ix::WebSocketMessageType::Open) { std::cout << "New connection" << std::endl; // A connection state object is available, and has a default id // You can subclass ConnectionState and pass an alternate factory // to override it. It is useful if you want to store custom // attributes per connection (authenticated bool flag, attributes, etc...) std::cout << "id: " << connectionState->getId() << std::endl; // The uri the client did connect to. std::cout << "Uri: " << msg->openInfo.uri << std::endl; std::cout << "Headers:" << std::endl; for (auto it : msg->openInfo.headers) { std::cout << it.first << ": " << it.second << std::endl; } } else if (msg->type == ix::WebSocketMessageType::Message) { // For an echo server, we just send back to the client whatever was received by the server // All connected clients are available in an std::set. See the broadcast cpp example. // Second parameter tells whether we are sending the message in binary or text mode. // Here we send it in the same mode as it was received. auto ws = webSocket.lock(); if (ws) { ws->send(msg->str, msg->binary); } } } ); } } ); auto res = server.listen(); if (!res.first) { // Error handling return 1; } // Per message deflate connection is enabled by default. It can be disabled // which might be helpful when running on low power devices such as a Rasbery Pi server.disablePerMessageDeflate(); // Run the server in the background. Server can be stoped by calling server.stop() server.start(); // Block until server.stop() is called. server.wait(); ``` -------------------------------- ### Start websocket proxy server with configuration file Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/ws.md Launches the websocket proxy server using a specified configuration file for hostname-based routing and listens on a custom port. ```bash ws proxy_server --config_path proxyConfig.json --port 8765 ``` -------------------------------- ### Start a basic websocket proxy server Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/ws.md Starts a websocket proxy server that forwards traffic to a specified remote host. It listens on a local port and passes all data to the remote server. ```bash ws proxy_server --remote_host ws://127.0.0.1:9000 -v Listening on 127.0.0.1:8008 ``` -------------------------------- ### Start WebSocket Server for Pushing Messages Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/performance.md Use this command to start a WebSocket server that continuously sends a specified message to all connected clients. This is useful for performance testing. ```bash ws push_server -q --send_msg 'yo' ``` -------------------------------- ### Start Server with Honcho Source: https://github.com/machinezone/ixwebsocket/blob/master/test/compatibility/python/websockets/README.md Initiates the server processes using honcho. This includes nginx, a send process, and the websocket server. ```bash $ honcho start 15:29:52 system | nginx.1 started (pid=75372) 15:29:52 system | send.1 started (pid=75373) 15:29:52 system | websocket_server.1 started (pid=75374) 15:29:53 send.1 | [2020-01-05 15:29:53.414] [info] ws_send: Connecting to url: wss://localhost:8765 15:29:53 send.1 | [2020-01-05 15:29:53.415] [info] ws_send: Connecting... 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] ws_send: connected 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] ws_send: Sending... 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Uri: / 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Headers: 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Connection: upgrade 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Date: Sun, 05 Jan 2020 23:29:53 GMT 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Sec-WebSocket-Accept: 2+7DV7Q0Ib3fxynZwaNTtsAepIk= 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Server: nginx/1.15.9 15:29:53 send.1 | [2020-01-05 15:29:53.436] [info] Upgrade: websocket 15:29:53 send.1 | [2020-01-05 15:29:53.633] [info] load file from disk completed in 197 15:29:54 send.1 | [2020-01-05 15:29:54.267] [info] ws_send: Step 0 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.269] [info] ws_send: Step 1 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.271] [info] ws_send: Step 2 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.273] [info] ws_send: Step 3 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.275] [info] ws_send: Step 4 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.277] [info] ws_send: Step 5 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.278] [info] ws_send: Step 6 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.280] [info] ws_send: Step 7 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.282] [info] ws_send: Step 8 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.284] [info] ws_send: Step 9 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.286] [info] ws_send: Step 10 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.288] [info] ws_send: Step 11 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.289] [info] ws_send: Step 12 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.291] [info] ws_send: Step 13 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.293] [info] ws_send: Step 14 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.295] [info] ws_send: Step 15 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.297] [info] ws_send: Step 16 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.298] [info] ws_send: Step 17 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.300] [info] ws_send: Step 18 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.302] [info] ws_send: Step 19 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.304] [info] ws_send: Step 20 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.306] [info] ws_send: Step 21 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.308] [info] ws_send: Step 22 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.309] [info] ws_send: Step 23 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.311] [info] ws_send: Step 24 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.313] [info] ws_send: Step 25 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.315] [info] ws_send: Step 26 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.317] [info] ws_send: Step 27 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.319] [info] ws_send: Step 28 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.320] [info] ws_send: Step 29 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.322] [info] ws_send: Step 30 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.324] [info] ws_send: Step 31 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.326] [info] ws_send: Step 32 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.328] [info] ws_send: Step 33 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.329] [info] ws_send: Step 34 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.331] [info] ws_send: Step 35 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.333] [info] ws_send: Step 36 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.335] [info] ws_send: Step 37 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.337] [info] ws_send: Step 38 out of 768 15:29:54 send.1 | [2020-01-05 15:29:54.339] [info] ws_send: Step 39 out of 768 ``` -------------------------------- ### Install Faye-WebSocket Gem Source: https://github.com/machinezone/ixwebsocket/blob/master/test/compatibility/ruby/README.md Installs the faye-websocket gem, which is necessary for WebSocket communication in Ruby. Ensure GEM_HOME is set correctly before running. ```bash export GEM_HOME=$HOME/local/gems bundle install faye-websocket ``` -------------------------------- ### Setup Docker for Travis CI Source: https://github.com/machinezone/ixwebsocket/wiki/Testing Prepare the Docker environment for running Travis CI builds locally. This involves creating a symbolic link to the Dockerfile and building the Docker image. ```bash ln -sf docker/Dockerfile.ubuntu_xenial Dockerfile make docker ``` -------------------------------- ### Build Docker Image with Docker Compose Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Build the Docker image using 'make docker' and then start the services with 'docker compose up'. This prepares the environment for running the 'ws' tool within a container. ```bash $ make docker ... $ docker compose up & ... $ docker exec -it ixwebsocket_ws_1 bash app@ca2340eb9106:~$ ws --help ws is a websocket tool ... ``` -------------------------------- ### HTTP Client Preparation and Synchronous Requests Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Prepare HTTP request arguments including custom headers, timeouts, and redirect options. Demonstrates synchronous HEAD, GET, and POST requests with parameters, form data, or a request body. ```cpp #include ... // // Preparation // HttpClient httpClient; HttpRequestArgsPtr args = httpClient.createRequest(); // Custom headers can be set WebSocketHttpHeaders headers; headers["Foo"] = "bar"; args->extraHeaders = headers; // Timeout options args->connectTimeout = connectTimeout; args->transferTimeout = transferTimeout; // Redirect options args->followRedirects = followRedirects; args->maxRedirects = maxRedirects; // Misc args->compress = compress; // Enable gzip compression args->verbose = verbose; args->logger = [](const std::string& msg) { std::cout << msg; }; // // Synchronous Request // HttpResponsePtr out; std::string url = "https://www.google.com"; // HEAD request out = httpClient.head(url, args); // GET request out = httpClient.get(url, args); // POST request with parameters HttpParameters httpParameters; httpParameters["foo"] = "bar"; // HTTP form data can be passed in as well, for multi-part upload of files HttpFormDataParameters httpFormDataParameters; httpParameters["baz"] = "booz"; out = httpClient.post(url, httpParameters, httpFormDataParameters, args); // POST request with a body out = httpClient.post(url, std::string("foo=bar"), args); // PUT and PATCH are available too. // // Result // auto statusCode = response->statusCode; // Can be HttpErrorCode::Ok, HttpErrorCode::UrlMalformed, etc... auto errorCode = response->errorCode; // 200, 404, etc... auto responseHeaders = response->headers; // All the headers in a special case-insensitive unordered_map of (string, string) auto body = response->body; // All the bytes from the response as an std::string auto errorMsg = response->errorMsg; // Descriptive error message in case of failure auto uploadSize = response->uploadSize; // Byte count of uploaded data auto downloadSize = response->downloadSize; // Byte count of downloaded data ``` -------------------------------- ### Start Transfer Server Source: https://github.com/machinezone/ixwebsocket/blob/master/ws/README.md Starts the ws transfer server, which operates on port 8080 by default. ```bash ws transfer ``` -------------------------------- ### Connect to WebSocket with Ping Interval Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/CHANGELOG.md Connect to a WebSocket server and set a custom ping interval. This example demonstrates how to use the --ping_interval option. ```bash IXWebSocket$ ws connect --ping_interval 2 wss://echo.websocket.org Type Ctrl-D to exit prompt... Connecting to url: wss://echo.websocket.org > ws_connect: connected [2020-03-17 23:53:02.726] [info] Uri: / [2020-03-17 23:53:02.726] [info] Headers: [2020-03-17 23:53:02.727] [info] Connection: Upgrade [2020-03-17 23:53:02.727] [info] Date: Wed, 18 Mar 2020 06:45:05 GMT [2020-03-17 23:53:02.727] [info] Sec-WebSocket-Accept: 0gtqbxW0aVL/QI/ICpLFnRaiKgA= [2020-03-17 23:53:02.727] [info] sec-websocket-extensions: [2020-03-17 23:53:02.727] [info] Server: Kaazing Gateway [2020-03-17 23:53:02.727] [info] Upgrade: websocket [2020-03-17 23:53:04.894] [info] Received pong [2020-03-17 23:53:06.859] [info] Received pong [2020-03-17 23:53:08.881] [info] Received pong [2020-03-17 23:53:10.848] [info] Received pong [2020-03-17 23:53:12.898] [info] Received pong [2020-03-17 23:53:14.865] [info] Received pong [2020-03-17 23:53:16.890] [info] Received pong [2020-03-17 23:53:18.853] [info] Received pong [2020-03-17 23:53:19.388] [info] ws_connect: connection closed: code 1000 reason Normal closure [2020-03-17 23:53:19.502] [info] Received 208 bytes [2020-03-17 23:53:19.502] [info] Sent 0 bytes ``` -------------------------------- ### WebSocket Client API Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Demonstrates the basic setup and usage of the IXWebSocket client, including setting the URL, configuring ping intervals, enabling/disabling message compression, setting message callbacks, and managing the connection lifecycle. ```APIDOC ## WebSocket Client API ### Description This section details the core API for creating and managing a WebSocket client. It covers setting the target URL, configuring connection parameters like ping intervals and message compression, defining message handling callbacks, and controlling the connection's start and stop actions. ### Basic Usage ```cpp #include // Initialize WebSocket object ix::WebSocket webSocket; // Set the WebSocket server URL std::string url("ws://localhost:8080/"); webSocket.setUrl(url); // Optional: Set ping interval to keep connections alive webSocket.setPingInterval(45); // seconds // Enable or disable per-message deflate compression webSocket.enablePerMessageDeflate(); // webSocket.disablePerMessageDeflate(); // Set a callback for receiving messages and events webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr& msg) { if (msg->type == ix::WebSocketMessageType::Message) { std::cout << msg->str << std::endl; } }); // Start the WebSocket client and its background thread webSocket.start(); // Send a text message webSocket.send("hello world"); // Send a binary message webSocket.sendBinary("some serialized binary data"); // Stop the WebSocket client webSocket.stop(); ``` ``` -------------------------------- ### Run WebSocket Echo Server with Authorization Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/ws.md Starts a WebSocket echo server that requires a specific value in the Authorization header for clients to connect. Shows server listening and new connection details. ```bash $ ws echo_server --http_authorization_header supersecret [2020-12-17 22:35:06.192] [info] Listening on 127.0.0.1:8008 [2020-12-17 22:35:08.735] [info] New connection [2020-12-17 22:35:08.735] [info] remote ip: 127.0.0.1 [2020-12-17 22:35:08.735] [info] id: 0 [2020-12-17 22:35:08.735] [info] Uri: / [2020-12-17 22:35:08.735] [info] Headers: [2020-12-17 22:35:08.735] [info] Authorization: supersecret [2020-12-17 22:35:08.735] [info] Connection: Upgrade [2020-12-17 22:35:08.735] [info] Host: localhost:8008 [2020-12-17 22:35:08.735] [info] Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=15; client_max_window_bits=15 [2020-12-17 22:35:08.735] [info] Sec-WebSocket-Key: eFF2Gf25dC7eC15Ab1135G== [2020-12-17 22:35:08.735] [info] Sec-WebSocket-Version: 13 [2020-12-17 22:35:08.735] [info] Upgrade: websocket [2020-12-17 22:35:08.735] [info] User-Agent: ixwebsocket/11.0.4 macos ssl/SecureTransport zlib 1.2.11 [2020-12-17 22:35:25.157] [info] Received 7 bytes ``` -------------------------------- ### Basic CMakeLists.txt Configuration Source: https://github.com/machinezone/ixwebsocket/blob/master/third_party/cpp-linenoise/example/CMakeLists.txt Sets the minimum required CMake version, includes the current directory for headers, and defines the C++ standard to C++1y. This is a foundational setup for most C++ CMake projects. ```cmake cmake_minimum_required(VERSION 3.0) include_directories(.) add_definitions("-std=c++1y") ``` -------------------------------- ### HTTP Server Custom Connection Callback Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Implement a custom callback to handle incoming HTTP requests on the server. This example demonstrates how to access request details and construct a custom HTTP response. ```cpp setOnConnectionCallback( [this](HttpRequestPtr request, std::shared_ptr connectionState) -> HttpResponsePtr { // Build a string for the response std::stringstream ss; ss << connectionState->getRemoteIp(); << " " << request->method << " " << request->uri; std::string content = ss.str(); return std::make_shared(200, "OK", HttpErrorCode::Ok, WebSocketHttpHeaders(), content); } ``` -------------------------------- ### Client Command to Send Large File over SSL Source: https://github.com/machinezone/ixwebsocket/blob/master/test/compatibility/python/websockets/README.md Builds the client, copies the executable, and sends a large file to the SSL-enabled websocket server. The `--verify_none` flag is used for simplicity in this example, but should be replaced with proper certificate verification in production. ```bash make ws_mbedtls && cp build/ws/ws /usr/local/bin/ws && ws send --verify_none wss://localhost:8766 /tmp/big_file ``` -------------------------------- ### Configure WebSocket Server Heartbeat Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md This example demonstrates how to configure an optional heartbeat (keep-alive) interval for the WebSocket server. The heartbeat interval can be set during server construction to a positive value in seconds to enable it, or to -1 to disable it (which is the default). ```cpp int pingIntervalSeconds = 45; ix::WebSocketServer server(port, host, backlog, maxConnections, handshakeTimeoutSecs, addressFamily, pingIntervalSeconds); ``` -------------------------------- ### HTTP Client Asynchronous Request with Chunk Callback Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Initiate an asynchronous HTTP GET request and process incoming data chunks in real-time using a callback. This is useful for handling large responses without accumulating them in memory. ```cpp // // Asynchronous Request // bool async = true; HttpClient httpClient(async); auto args = httpClient.createRequest(url, HttpClient::kGet); // If you define a chunk callback it will be called repeteadly with the // incoming data. This allows to process data on the go or write it to disk // instead of accumulating the data in memory. args.onChunkCallback = [](const std::string& data) { // process data }; // Push the request to a queue, bool ok = httpClient.performRequest(args, [](const HttpResponsePtr& response) { // This callback execute in a background thread. Make sure you uses appropriate protection such as mutex auto statusCode = response->statusCode; // acess results // response->body is empty if onChunkCallback was used } ); // ok will be false if your httpClient is not async // A request in progress can be cancelled by setting the cancel flag. It does nothing if the request already completed. args->cancel = true; ``` -------------------------------- ### IXWebSocket Hello World Client Source: https://github.com/machinezone/ixwebsocket/blob/master/README.md This C++ code demonstrates a minimal IXWebSocket client. It initializes the network system, sets up a WebSocket object, connects to a public echo server, defines a message callback for handling incoming messages and connection events, and then sends messages received from standard input to the server. Required on Windows: ix::initNetSystem(). ```cpp /* * main.cpp * Author: Benjamin Sergeant * Copyright (c) 2020 Machine Zone, Inc. All rights reserved. * * Super simple standalone example. See ws folder, unittest and doc/usage.md for more. * * On macOS * $ mkdir -p build ; (cd build ; cmake -DUSE_TLS=1 .. ; make -j ; make install) * $ clang++ --std=c++11 --stdlib=libc++ main.cpp -lixwebsocket -lz -framework Security -framework Foundation * $ ./a.out * * Or use cmake -DBUILD_DEMO=ON option for other platforms */ #include #include #include #include int main() { // Required on Windows ix::initNetSystem(); // Our websocket object ix::WebSocket webSocket; // Connect to a server with encryption // See https://machinezone.github.io/IXWebSocket/usage/#tls-support-and-configuration // https://github.com/machinezone/IXWebSocket/issues/386#issuecomment-1105235227 (self signed certificates) std::string url("wss://echo.websocket.org"); webSocket.setUrl(url); std::cout << "Connecting to " << url << "..." << std::endl; // Setup a callback to be fired (in a background thread, watch out for race conditions !) // when a message or an event (open, close, error) is received webSocket.setOnMessageCallback([](const ix::WebSocketMessagePtr& msg) { if (msg->type == ix::WebSocketMessageType::Message) { std::cout << "received message: " << msg->str << std::endl; std::cout << "> " << std::flush; } else if (msg->type == ix::WebSocketMessageType::Open) { std::cout << "Connection established" << std::endl; std::cout << "> " << std::flush; } else if (msg->type == ix::WebSocketMessageType::Error) { // Maybe SSL is not configured properly std::cout << "Connection error: " << msg->errorInfo.reason << std::endl; std::cout << "> " << std::flush; } } ); // Now that our callback is setup, we can start our background thread and receive messages webSocket.start(); // Send a message to the server (default to TEXT mode) webSocket.send("hello world"); // Display a prompt std::cout << "> " << std::flush; std::string text; // Read text from the console and send messages in text mode. // Exit with Ctrl-D on Unix or Ctrl-Z on Windows. while (std::getline(std::cin, text)) { webSocket.send(text); std::cout << "> " << std::flush; } return 0; } ``` -------------------------------- ### Run a WebSocket Server Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md This snippet shows how to initialize and run a WebSocket server on a specified host and port. It includes setting up a client message callback to handle connection openings and incoming messages, and demonstrates basic error handling for the server listen operation. ```cpp #include ... // Run a server on localhost at a given port. // Bound host name, max connections and listen backlog can also be passed in as parameters. int port = 8008; std::string host("127.0.0.1"); // If you need this server to be accessible on a different machine, use "0.0.0.0" ix::WebSocketServer server(port, host); server.setOnClientMessageCallback([](std::shared_ptr connectionState, ix::WebSocket & webSocket, const ix::WebSocketMessagePtr & msg) { // The ConnectionState object contains information about the connection, // at this point only the client ip address and the port. std::cout << "Remote ip: " << connectionState->getRemoteIp() << std::endl; if (msg->type == ix::WebSocketMessageType::Open) { std::cout << "New connection" << std::endl; // A connection state object is available, and has a default id // You can subclass ConnectionState and pass an alternate factory // to override it. It is useful if you want to store custom // attributes per connection (authenticated bool flag, attributes, etc...) std::cout << "id: " << connectionState->getId() << std::endl; // The uri the client did connect to. std::cout << "Uri: " << msg->openInfo.uri << std::endl; std::cout << "Headers:" << std::endl; for (auto it : msg->openInfo.headers) { std::cout << "\t" << it.first << ": " << it.second << std::endl; } } else if (msg->type == ix::WebSocketMessageType::Message) { // For an echo server, we just send back to the client whatever was received by the server // All connected clients are available in an std::set. See the broadcast cpp example. // Second parameter tells whether we are sending the message in binary or text mode. // Here we send it in the same mode as it was received. std::cout << "Received: " << msg->str << std::endl; webSocket.send(msg->str, msg->binary); } }); auto res = server.listen(); if (!res.first) { // Error handling return 1; } // Per message deflate connection is enabled by default. It can be disabled // which might be helpful when running on low power devices such as a Rasbery Pi server.disablePerMessageDeflate(); // Run the server in the background. Server can be stoped by calling server.stop() server.start(); // Block until server.stop() is called. server.wait(); ``` -------------------------------- ### Basic Usage of Linenoise Library Source: https://github.com/machinezone/ixwebsocket/blob/master/third_party/cpp-linenoise/README.md Demonstrates setting up completion callbacks, multi-line mode, history management, and reading user input with history saving. Ensure history file path is correctly specified. ```cpp #include "linenoise.hpp" ... const auto path = "history.txt"; // Setup completion words every time when a user types linenoise::SetCompletionCallback([](const char* editBuffer, std::vector& completions) { if (editBuffer[0] == 'h') { completions.push_back("hello"); completions.push_back("hello there"); } }); // Enable the multi-line mode linenoise::SetMultiLine(true); // Set max length of the history linenoise::SetHistoryMaxLen(4); // Load history linenoise::LoadHistory(path); while (true) { // Read line std::string line; auto quit = linenoise::Readline("hello> ", line); if (quit) { break; } cout << "echo: '" << line << "'" << endl; // Add text to history linenoise::AddHistory(line.c_str()); } // Save history linenoise::SaveHistory(path); ``` -------------------------------- ### Configure Remote URL Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/usage.md Set and query the remote WebSocket URL. Ensure to call stop() and start() to apply changes and reconnect. ```cpp std::string url("wss://example.com"); websocket.configure(url); ``` -------------------------------- ### Linenoise API Reference Source: https://github.com/machinezone/ixwebsocket/blob/master/third_party/cpp-linenoise/README.md Provides the function signatures for the linenoise C++ API, including readline, history management, and completion callback setup. ```cpp namespace linenoise; std::string Readline(const char* prompt); void SetMultiLine(bool multiLineMode); typedef std::function& completions)> CompletionCallback; void SetCompletionCallback(CompletionCallback fn); bool SetHistoryMaxLen(size_t len); bool LoadHistory(const char* path); bool SaveHistory(const char* path); bool AddHistory(const char* line); const std::vector& GetHistory(); ``` -------------------------------- ### Configure CMake for vcpkg Integration Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Set the CMake toolchain file to point to vcpkg and find the installed IXWebSocket library. This is crucial for CMake to locate the library and headers. ```cmake set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") # this is super important in order for cmake to include the vcpkg search/lib paths! # find library and its headers find_path(IXWEBSOCKET_INCLUDE_DIR ixwebsocket/IXWebSocket.h) find_library(IXWEBSOCKET_LIBRARY ixwebsocket) # include headers include_directories(${IXWEBSOCKET_INCLUDE_DIR}) # ... target_link_libraries(${PROJECT_NAME} ... ${IXWEBSOCKET_LIBRARY}) # Cmake will automatically fail the generation if the lib was not found, i.e is set to NOTFOUND ``` -------------------------------- ### Adding Executable Target in CMake Source: https://github.com/machinezone/ixwebsocket/blob/master/third_party/cpp-linenoise/example/CMakeLists.txt Adds an executable target named 'example' which is built from the 'example.cpp' source file. This command links the source code to the final executable. ```cmake add_executable(example example.cpp) ``` -------------------------------- ### Build Static Library for macOS/iOS Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Prepare the build directory and execute the iOS build script to create static libraries for macOS and iOS. ```bash mkdir build cd build ./../tools/build_ios.sh ``` -------------------------------- ### Build Static Library with CMake Source: https://github.com/machinezone/ixwebsocket/blob/master/docs/build.md Create a build directory, configure with CMake, and build the static library. Assumes TLS support is enabled. ```bash mkdir build #make a build dir so that you can build out of tree cd build cmake -DUSE_TLS=1 .. make -j ``` -------------------------------- ### ws CLI Help Source: https://github.com/machinezone/ixwebsocket/blob/master/ws/README.md Displays the main help message for the ws command-line tool, listing available subcommands. ```bash ws --help ```