AUI Framework  develop
Cross-platform base for C++ UI apps
Loading...
Searching...
No Matches
AWebsocket.h
    1/*
    2 * AUI Framework - Declarative UI toolkit for modern C++20
    3 * Copyright (C) 2020-2025 Alex2772 and Contributors
    4 *
    5 * SPDX-License-Identifier: MPL-2.0
    6 *
    7 * This Source Code Form is subject to the terms of the Mozilla Public
    8 * License, v. 2.0. If a copy of the MPL was not distributed with this
    9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
   10 */
   11
   12//
   13// Created by alex2772 on 9/5/22.
   14//
   15
   16#pragma once
   17
   18
   19#include "ACurl.h"
   20#include "AUI/Common/AByteBufferView.h"
   21#include "AUI/Common/AOptional.h"
   22#include "AUI/Common/AString.h"
   23#include "AUI/IO/ADynamicPipe.h"
   24
   29class API_AUI_CURL AWebsocket: public ACurl, public IOutputStream {
   30    friend class WebsocketTest_Receive1_Test;
   31    friend class WebsocketTest_Receive2_Test;
   32public:
   33    AWebsocket(const AString& url, AString key = generateKeyString());
   34    void write(const char* src, size_t size) override;
   35
   36    void close() override;
   37
   38    enum class Opcode {
   39        CONTINUATION = 0x0,
   40        TEXT = 0x1,
   41        BINARY = 0x2,
   42        CLOSE = 0x8,
   43        PING = 0x9,
   44        PONG = 0xa,
   45    };
   46
   47private:
   48    AString mKey;
   49    ADynamicPipe mRead;
   50    bool mAccepted = false;
   51
   79    struct Header {
   80        /* first byte: fin + opcode */
   81        uint8_t opcode: 4;
   82        uint8_t rsv: 3;
   83        uint8_t fin: 1;
   84
   85        /* second byte: mask + payload length */
   86        uint8_t payload_len: 7; /* if 126, uses extra 2 bytes (uint16_t)
   87                                 * if 127, uses extra 8 bytes (uint64_t)
   88                                 * if <=125 is self-contained
   89                                 */
   90        uint8_t mask: 1; /* if 1, uses 4 extra bytes */
   91    };
   92
   93    static AString generateKeyString();
   94
   95    void writeRaw(const char* src, size_t size);
   96    void writeRawMasked(const std::uint8_t mask[4], AByteBufferView message);
   97    void writeMessage(Opcode opcode, AByteBufferView message);
   98
   99    std::size_t onDataReceived(AByteBufferView data);
  100    std::size_t decodeOnePacket(AByteBufferView data);
  101    std::size_t onDataSend(char* dst, std::size_t maxLen);
  102
  103    AWebsocket(): ACurl(ACurl::Builder("localhost")) {} // for tests
  104
  105    AOptional<AByteBuffer> mTrailingBuffer;
  106
  107signals:
  108    emits<> connected;
  109    emits<AByteBuffer> received;
  110    emits<AString /* message */> websocketClosed;
  111};
  112
  113AUI_ENUM_VALUES(AWebsocket::Opcode,
  114                AWebsocket::Opcode::CONTINUATION,
  115                AWebsocket::Opcode::TEXT,
  116                AWebsocket::Opcode::BINARY,
  117                AWebsocket::Opcode::CLOSE,
  118                AWebsocket::Opcode::PING,
  119                AWebsocket::Opcode::PONG
  120)
An asynchronous buffer that converts an IInputStream to IOutputStream (and otherwise).
Definition ADynamicPipe.h:29
Represents a Unicode character string.
Definition AString.h:38
void close() override
Breaks curl loop in the run() method, closing underlying curl connection.
void write(const char *src, size_t size) override
Writes exact size bytes to stream. Blocking (waiting for write all data) is allowed.
Definition IOutputStream.h:18
ASignal< Args... > emits
A signal declaration.
Definition ASignal.h:572
#define AUI_ENUM_VALUES(enum_t,...)
Defines all enum values for AEnumerate.
Definition AEnumerate.h:208