IXWebSocket

repository·master·Indexed 21 days ago

https://github.com/machinezone/ixwebsocket

A lightweight C++ library for high-performance WebSocket client and server development. It features minimal dependencies (no Boost), automatic reconnection with exponential backoff, and support for per message deflate compression. Designed for cross-platform use, including iOS, Android, Linux, Windows, and macOS, with support for TLS/SSL via AppleSSL, OpenSSL, or mbedTLS. Includes the 'ws' command-line tool for tasks such as file transfers, group chat, and HTTP requests via the 'curl' subcommand.

Tokens
12.9K
Snippets
37
Records
46
Agent score
68%

What's inside IXWebSocket

  1. Use the `ws` command-line tool

    master

    The ws CLI tool is a utility designed to exercise the IXWebSocket codebase and provide practical examples of websocket and HTTP operations. It supports various subcommands for connecting, sending/receiving files, running servers, and performing HTTP requests.

    ws [OPTIONS] SUBCOMMAND
    
    Subcommands:
      send                        Send a file
      receive                     Receive a file
      transfer                    Broadcasting server
      connect                     Connect to a remote server
      chat                        Group chat
      echo_server                 Echo server
      broadcast_server            Broadcasting server
      ping                        Ping pong
      curl                        HTTP Client
      httpd                       HTTP server
  2. Overview of IXWebSocket C++ code organization

    master

    The library is organized into public interfaces for clients and servers, and private modules for low-level transport and handshake logic:

    Public Interface

    • IXWebSocket: The primary interface for C++ clients. It manages the receiving background thread, automatic reconnection, and simple WebSocket Pings. It has no dependencies on IX internal modules.
    • IXWebSocketServer: Used to run a server. It provides a unique WebSocket object for each connection, with each connection handled in its own OS thread.

    Private Modules

    • IXWebSocketTransport: Handles low-level WebSocket code, framing, and raw socket management.
    • IXWebSocketHandshake: Manages the connection establishment between client and server.
    • Socket Handlers:
      • IXWebSocket: Handles unencrypted ws:// sockets.
      • IXWebSocketAppleSSL: Handles wss:// via AppleSSL (iOS/macOS).
      • IXWebSocketOpenSSL: Handles wss:// via OpenSSL (Android/Linux/macOS).
    • IXSocketConnect: Manages connecting to the remote host.
    • IXDNSLookup: Performs asynchronous DNS resolution that can be interrupted.
    +-----------------------+ --- Public
    |                       | Start the receiving Background thread. Auto reconnection. Simple websocket Ping.
    |  IXWebSocket          | Interface used by C++ test clients. No IX dependencies.
    |                       |
    +-----------------------+
    |                       |
    |  IXWebSocketServer    | Run a server and give each connections its own WebSocket object.
    |                       | Each connection is handled in a new OS thread.
    |                       |
    +-----------------------+ --- Private
    |                       |
    |  IXWebSocketTransport | Low level websocket code, framing, managing raw socket. Adapted from easywsclient.
    |                       |
    +-----------------------+
    |                       |
    |  IXWebSocketHandshake | Establish the connection between client and server.
    |                       |
    +-----------------------+
    |                       |
    |  IXWebSocket          | ws://  Unencrypted Socket handler
    |  IXWebSocketAppleSSL  | wss:// TLS encrypted Socket AppleSSL handler. Used on iOS and macOS
    |  IXWebSocketOpenSSL   | wss:// TLS encrypted Socket OpenSSL handler.  Used on Android and Linux
    |                                                                              Can be used on macOS too.
    +-----------------------+
    |                       |
    |  IXSocketConnect      | Connect to the remote host (client).
    |                       |
    +-----------------------+
    |                       |
    |  IXDNSLookup          | Does DNS resolution asynchronously so that it can be interrupted.
    |                       |
    +-----------------------+
  3. Understand automatic reconnection behavior

    master
    By default, if the remote server breaks the connection, IXWebSocket will attempt to reconnect perpetually. It uses an exponential backoff strategy, with the retry frequency capped at a maximum of one attempt every 10 seconds. This automatic reconnection behavior can be disabled if required for your application logic.
  4. Use Per Message Deflate compression

    master
    The library supports the per message deflate compression option. This can provide significant bandwidth savings (up to 20x) when messages are similar, which is common in use cases like chat applications. The implementation supports all features of the WebSocket specification for this compression.
  5. Quickstart: Create a simple WebSocket client

    master

    IXWebSocket is a C++ library for WebSocket client and server development with minimal dependencies. To create a basic client:

    1. Initialize the network system: On Windows, you must call ix::initNetSystem().
    2. Create a ix::WebSocket object: This object manages your connection.
    3. Set the URL: Use webSocket.setUrl(url) to specify the server address (e.g., wss://echo.websocket.org).
    4. Set a Message Callback: Use webSocket.setOnMessageCallback() to handle incoming messages and events like Open, Close, or Error. Note that callbacks are executed in a background thread.
    5. Start the connection: Call webSocket.start() to begin the background thread.
    6. Send messages: Use webSocket.send(text) to transmit data to the server.

    Important: Because callbacks run in a background thread, be mindful of race conditions when accessing shared data.

    #include <ixwebsocket/IXNetSystem.h>
    #include <ixwebsocket/IXWebSocket.h>
    #include <ixwebsocket/IXUserAgent.h>
    #include <iostream>
    
    int main()
    {
        // Required on Windows
        ix::initNetSystem();
    
        // Our websocket object
        ix::WebSocket webSocket;
    
        // Connect to a server with encryption
        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 !)
        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)
                {
                    std::cout << "Connection error: " << msg->errorInfo.reason << std::endl;
                    std::cout << "> " << std::flush;
                }
            }
        );
    
        // Start the background thread
        webSocket.start();
    
        // Send a message
        webSocket.send("hello world");
    
        std::string text;
        while (std::getline(std::cin, text))
        {
            webSocket.send(text);
            std::cout << "> " << std::flush;
        }
    
        return 0;
    }
  6. Build IXWebSocket as a static library

    master

    You can build IXWebSocket as a static library using CMake. It is recommended to perform an out-of-tree build by creating a separate build directory.

    For mobile platforms, specialized build scripts are provided in the tools folder to handle Android and iOS/macOS specific requirements.

    ### Standard Static Library Build
    ```bash
    mkdir build
    cd build
    cmake -DUSE_TLS=1 ..
    make -j

    Android Build

    mkdir build
    cd build
    ./../tools/build_android.sh
    make -j

    macOS & iOS Build

    mkdir build
    cd build
    ./../tools/build_ios.sh
  7. Build and Install IXWebSocket on macOS

    master

    To build and install the library on macOS using CMake and Clang, follow these steps:

    1. Create a build directory: mkdir -p build.
    2. Run CMake with TLS enabled: cd build && cmake -DUSE_TLS=1 ...
    3. Compile and install: make -j && make install.
    4. Compile your application (example using main.cpp): clang++ --std=c++11 --stdlib=libc++ main.cpp -lixwebsocket -lz -framework Security -framework Foundation
    # 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
  8. Perform HTTP requests with `ws curl`

    master

    The ws curl subcommand provides an HTTP client with syntax compatible with curl. It can be used to fetch pages, perform POST requests with form data, and pass custom headers.

    # Make a HEAD request
    ws curl -I https://www.google.com/
    
    # Make a POST request with form data
    ws curl -F foo=bar https://httpbin.org/post
    
    # Pass a custom header
    ws curl -F foo=bar -H 'my_custom_header: baz' https://httpbin.org/post
  9. Configure a WebSocket proxy with `ws proxy_server`

    master

    The ws proxy_server can act as a simple proxy to a single remote host or a complex proxy that redirects traffic to different servers based on the hostname.

    For complex routing, provide a JSON configuration file via the --config_path option. The JSON file should map hostnames to target WebSocket URLs (e.g., "echo.jeanserge.com": "ws://localhost:8008").

    # Simple proxy to a single remote host
    ws proxy_server --remote_host ws://127.0.0.1:9000 -v
    
    # Complex proxy using a JSON configuration file
    ws proxy_server --config_path proxyConfig.json --port 8765
  10. Update ixwebsocket in VCPKG

    master

    To update the ixwebsocket port in VCPKG, you must first obtain the latest release tag and its SHA512 checksum from the IXWebSocket releases page.

    1. Download and Verify: Download the release archive (e.g., .tar.gz) and verify its integrity using openssl sha512.
    2. Modify Port Files: Update the following files in your VCPKG fork:
      • ports/ixwebsocket/CONTROL: Update the Version field.
      • ports/ixwebsocket/portfile.cmake: Update the REF (the version tag) and the SHA512 hash within the vcpkg_from_github function.
    3. Submit Changes: Create a new feature branch in your VCPKG fork, commit the changes, and push the branch to your origin to open a Pull Request.
    # 1. Download the release
    curl -s -O -L https://github.com/machinezone/IXWebSocket/archive/v9.1.9.tar.gz
    
    # 2. Verify the checksum
    openssl sha512 v9.1.9.tar.gz
    
    # 3. Update VCPKG files (example diff)
    # ports/ixwebsocket/CONTROL: Version: 9.1.9
    # ports/ixwebsocket/portfile.cmake: REF v9.1.9, SHA512 <new_hash>
    
    # 4. Git workflow for VCPKG fork
    git co -b feature/ixwebsocket_9.1.9
    git commit -am 'ixwebsocket: update to 9.1.9'
    git push --set-upstream origin feature/ixwebsocket_9.1.9
  11. Initialize the network system on Windows

    master

    On Windows, you must initialize the network system once using ix::initNetSystem() and clean it up using ix::uninitNetSystem(). This should typically be done in your main function to ensure the underlying Winsock system is ready for use.

    #include <ixwebsocket/IXNetSystem.h>
    
    int main()
    {
        ix::initNetSystem();
    
        // ... your application logic ...
    
        ix::uninitNetSystem();
        return 0;
    }
  12. Run an echo server with `ws echo_server`

    master

    The ws echo_server command starts a server that responds to clients with whatever data they send. You can enforce a simple authorization scheme by using the --http_authorization_header flag, which requires clients to provide a specific value in their Authorization header to connect.

    # Start an echo server requiring a specific authorization header
    ws echo_server --http_authorization_header supersecret