A high-performance C++ framework that enables multiple clients to share a single WebSocket connection through efficient inter-process communication (IPC) using shared memory queues.
WebsocketProxy solves the problem of connection limitations by allowing multiple client applications to share a single WebSocket connection. Originally designed for Alpaca Markets, which restricts accounts to one WebSocket connection, it enables multiple trading strategies to receive real-time market data simultaneously.
Key Features:
- Zero-Copy IPC: Lock-free shared memory queues for high-performance communication
- Protocol-Agnostic: Transparent message pass-through works with any WebSocket API
- Automatic Lifecycle Management: Server spawns on first client connection and terminates when all clients disconnect
- Header-Only Client: Lightweight, easy-to-integrate client library
- Multi-Platform: Windows support with cross-platform design
- Resource Efficient: Single WebSocket connection serves unlimited clients
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Client 1   │     │  Client 2   │     │  Client N   │
│             │     │             │     │             │
└──────┬──────┘     └──────┬──────┘     └──────┬──────┘
       │                   │                   │
       │    Shared Memory Queues (IPC)         │
       └───────────────┬───────────────────────┘
                       │
              ┌────────▼────────┐
              │ Proxy Server    │
              │ (websocket_     │
              │  proxy.exe)     │
              └────────┬────────┘
                       │
                       │ Single WebSocket
                       │
              ┌────────▼────────┐
              │ Remote Server   │
              │ (e.g., Alpaca)  │
              └─────────────────┘
- 
Proxy Server ( websocket_proxy.exe)- Maintains single WebSocket connection to remote server
- Manages IPC via lock-free shared memory queues
- Automatically spawned by first client connection
- Routes messages between clients and remote server
- Terminates when all clients disconnect
 
- 
Proxy Client (Header-only library) - Lightweight client library for your applications
- Derives from WebsocketProxyCallbackinterface
- Handles spawning and communication with proxy server
- Provides async/sync WebSocket operations
- Automatic heartbeat and reconnection handling
 
Download the latest release from the releases page, extract it, and copy the contents to your project:
# Extract release
unzip websocket_proxy_v1.1.1.1.zip
# Copy headers to your project
cp -r include /path/to/your/project/
# Copy proxy server executable
cp bin/websocket_proxy.exe /path/to/your/project/bin/- Implement the callback interface:
#include <websocket_proxy/websocket_proxy_client.h>
class MyWebSocketClient : public websocket_proxy::WebsocketProxyCallback {
public:
    void onWebsocketProxyServerDisconnected() override {
        // Handle proxy server disconnect
    }
    void onWebsocketOpened(uint64_t id) override {
        // WebSocket connection established
        std::cout << "Connected: " << id << std::endl;
    }
    void onWebsocketClosed(uint64_t id) override {
        // WebSocket connection closed
    }
    void onWebsocketError(uint64_t id, const char* err, uint32_t len) override {
        // Handle WebSocket errors
        std::cerr << "Error: " << std::string(err, len) << std::endl;
    }
    void onWebsocketData(uint64_t id, const char* data, uint32_t len, uint32_t remaining) override {
        // Process incoming data
        std::string message(data, len);
        std::cout << "Received: " << message << std::endl;
    }
};- Create and use the client:
#include <websocket_proxy/websocket_proxy_client.h>
int main() {
    MyWebSocketClient callback;
    // Initialize client with callback and proxy server path
    websocket_proxy::WebsocketProxyClient client(
        &callback,
        "MyClient",                                    // Client name
        "./bin/websocket_proxy.exe"                    // Proxy server path
    );
    // Open WebSocket connection
    auto [id, is_new] = client.openWebSocket(
        "wss://stream.data.alpaca.markets/v2/iex",    // WebSocket URL
        "your_api_key"                                 // API key (optional)
    );
    if (id) {
        // Send messages
        std::string msg = R"({"action":"subscribe","bars":["AAPL"]})";
        client.send(id, msg.c_str(), msg.size());
        // Keep running...
        std::this_thread::sleep_for(std::chrono::seconds(60));
        // Close connection
        client.closeWebSocket(id);
    }
    return 0;
}For a complete example, see the Alpaca WebSocket client in the example/ directory.
- C++20 compatible compiler (MSVC 2019+, GCC 10+, Clang 12+)
- CMake 3.16 or higher
- vcpkg for dependency management
- Dependencies:
- Boost.Beast (WebSocket client)
- OpenSSL (TLS/SSL support)
- slick_logger (automatically fetched)
- slick_queue (automatically fetched)
 
# Clone and bootstrap vcpkg
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
# Windows
./bootstrap-vcpkg.bat
# Linux/macOS
./bootstrap-vcpkg.sh
# Install dependencies
./vcpkg install boost-beast:x64-windows-static
./vcpkg install openssl:x64-windows-static# Clone repository
git clone https://github.com/kzhdev/websocket_proxy.git
cd websocket_proxy
# Configure with CMake (Windows example)
cmake -S . -B build \
  -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake \
  -DCMAKE_BUILD_TYPE=Release
# Build
cmake --build ./build --config Release -j
# Output will be in build/bin/Release/websocket_proxy.exe
# Headers in build/dist/include/# Build without example
cmake -S . -B build -DBUILD_EXAMPLE=OFF
# Debug build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
# Create distribution package (Release only)
# Automatically creates websocket_proxy_<version>.zip in build/dist/
cmake --build ./build --config Release# Install to system (optional)
cmake --install ./build --prefix /usr/localImplement this interface to handle WebSocket events:
class WebsocketProxyCallback {
public:
    virtual ~WebsocketProxyCallback() = default;
    // Called when proxy server disconnects
    virtual void onWebsocketProxyServerDisconnected() = 0;
    // Called when WebSocket connection opens
    virtual void onWebsocketOpened(uint64_t id) = 0;
    // Called when WebSocket connection closes
    virtual void onWebsocketClosed(uint64_t id) = 0;
    // Called on WebSocket errors
    virtual void onWebsocketError(uint64_t id, const char* err, uint32_t len) = 0;
    // Called when data is received
    // remaining: bytes remaining in current message (for fragmented messages)
    virtual void onWebsocketData(uint64_t id, const char* data, uint32_t len, uint32_t remaining) = 0;
    // Optional: Logging callbacks
    virtual void logError(std::function<std::string()>&&) {}
    virtual void logWarning(std::function<std::string()>&&) {}
    virtual void logInfo(std::function<std::string()>&&) {}
    virtual void logDebug(std::function<std::string()>&&) {}
};// Constructor
WebsocketProxyClient(
    WebsocketProxyCallback* callback,
    std::string&& name,              // Client identifier
    std::string&& proxy_exe_path     // Path to websocket_proxy.exe
);
// Open WebSocket (synchronous) - returns (connection_id, is_new_connection)
std::pair<uint64_t, bool> openWebSocket(
    const std::string& url,
    const std::string& api_key = ""
);
// Open WebSocket (asynchronous)
bool openWebSocketAsync(
    const std::string& url,
    const std::string& api_key = ""
);
// Close WebSocket (id=0 closes all)
bool closeWebSocket(uint64_t id = 0);
// Send data to WebSocket
void send(uint64_t id, const char* msg, uint32_t len);
// Subscribe to symbol (for trading APIs)
bool subscribe(
    uint64_t id,
    const std::string& symbol,
    const char* subscription_request,
    uint32_t request_len,
    SubscriptionType type,
    bool& existing
);
// Unsubscribe from symbol
bool unsubscribe(
    uint64_t id,
    const std::string& symbol,
    const char* unsubscription_request,
    uint32_t request_len
);
// Set logging level
bool setLogLevel(LogLevel::level_enum level);
// Get server process ID
uint64_t serverId() const noexcept;- Zero-copy IPC: Shared memory queues eliminate data copying between processes
- Lock-free: Wait-free algorithms for high-throughput communication
- Low latency: Optimized message routing with minimal overhead
- Scalable: Supports unlimited clients with constant memory per client
- Trading Systems: Share market data WebSocket across multiple strategies
- Real-time Data: Multiple consumers for single data stream
- API Rate Limiting: Multiplex API connections with connection limits
- Resource Optimization: Reduce connection overhead in microservices
- Development/Testing: Test multiple clients with single connection
- Ensure websocket_proxy.exepath is correct
- Check Windows Defender/Firewall isn't blocking execution
- Verify shared memory permissions
- Increase timeout in waitForResponse()calls
- Check network connectivity to remote server
- Verify WebSocket URL is correct
- Monitor shared queue sizes for memory leaks
- Ensure proper cleanup on client disconnect
- Check for deadlocks in message handling
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
This project is licensed under the MIT License. See the LICENSE file for details.
- Built with Boost.Beast for WebSocket implementation
- Uses slick_queue for lock-free IPC
- Logging powered by slick_logger
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Version: 1.1.1.1 Author: Kun Zhao Copyright: © 2024-2025