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-2024 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)
Acts like std::string_view but for AByteBuffer.
Definition AByteBufferView.h:24
Definition ACurl.h:176
virtual void close()
Breaks curl loop in the run() method, closing underlying curl connection.
Definition ACurl.cpp:354
An asynchronous buffer that converts an IInputStream to IOutputStream (and otherwise).
Definition ADynamicPipe.h:29
Utility wrapper implementing the stack-allocated (fast) optional idiom.
Definition AOptional.h:32
Represents a Unicode character string.
Definition AString.h:37
Definition IOutputStream.h:18
virtual void write(const char *src, size_t size)=0
Writes exact size bytes to stream. Blocking (waiting for write all data) is allowed.
ASignal< Args... > emits
A signal declaration.
Definition ASignal.h:348
#define AUI_ENUM_VALUES(enum_t,...)
Defines all enum values for AEnumerate.
Definition AEnumerate.h:208