A lot of query reworking

This commit is contained in:
WolverinDEV
2021-01-28 20:59:15 +01:00
parent 9a5aa1d42b
commit 902b1f3511
58 changed files with 1615 additions and 1012 deletions
+19 -37
View File
@@ -1,4 +1,5 @@
#include "WebClient.h"
#include "../shared/RawCommand.h"
#include <log/LogUtils.h>
#include <src/server/VoiceServer.h>
#include <src/InstanceHandler.h>
@@ -83,38 +84,29 @@ void WebClient::handleMessageRead(int fd, short, void *) {
return;
}
auto pbuffer = buffer::allocate_buffer((size_t) length);
pbuffer.write(buffer, length);
auto command = command::ReassembledCommand::allocate((size_t) length);
memcpy(command->command(), buffer, (size_t) length);
{
lock_guard lock(this->queue_mutex);
this->queue_read.push_back(std::move(pbuffer));
}
this->registerMessageProcess();
this->command_queue->enqueue_command_execution(command);
}
void WebClient::enqueue_raw_packet(const pipes::buffer_view &msg) {
auto buffer = msg.owns_buffer() ? msg.own_buffer() : msg.own_buffer(); /* TODO: Use buffer::allocate_buffer(...) */
auto buffer = msg.own_buffer(); /* TODO: Use buffer::allocate_buffer(...) */
{
lock_guard queue_lock(this->queue_mutex);
this->queue_write.push_back(buffer);
}
{
lock_guard lock(this->event_mutex);
if(this->writeEvent)
if(this->writeEvent) {
event_add(this->writeEvent, nullptr);
}
}
this->connectionStatistics->logOutgoingPacket(stats::ConnectionStatistics::category::COMMAND, buffer.length());
}
void WebClient::registerMessageProcess() {
auto weakLock = this->_this;
if(serverInstance->getVoiceServerManager()->getState() == VirtualServerManager::STARTED)
serverInstance->getVoiceServerManager()->get_executor_loop()->schedule(this->event_handle_packet);
}
inline bool is_ssl_handshake_header(const pipes::buffer_view& buffer) {
inline bool is_ssl_handshake_header(const std::string_view& buffer) {
if(buffer.length() < 0x05) return false; //Header too small!
if(buffer[0] != 0x16) return false; //recordType=handshake
@@ -125,36 +117,26 @@ inline bool is_ssl_handshake_header(const pipes::buffer_view& buffer) {
return true;
}
void WebClient::processNextMessage(const std::chrono::system_clock::time_point& /* scheduled */) {
bool WebClient::process_next_message(const std::string_view &buffer) {
lock_guard execute_lock(this->execute_mutex);
if(this->state != ConnectionState::INIT_HIGH && this->state != ConnectionState::INIT_LOW && this->state != ConnectionState::CONNECTED)
return;
unique_lock buffer_lock(this->queue_mutex);
if(this->queue_read.empty())
return;
auto buffer = this->queue_read.front();
this->queue_read.pop_front();
bool has_next = !this->queue_read.empty();
buffer_lock.unlock();
if(this->state != ConnectionState::INIT_HIGH && this->state != ConnectionState::INIT_LOW && this->state != ConnectionState::CONNECTED) {
return false;
}
this->connectionStatistics->logIncomingPacket(stats::ConnectionStatistics::category::COMMAND, buffer.length());
if(!this->ssl_detected) {
this->ssl_detected = true;
this->ssl_encrypted = is_ssl_handshake_header(buffer);
if(this->ssl_encrypted)
if(this->ssl_encrypted) {
logMessage(this->getServerId(), "[{}] Using encrypted basic connection.", CLIENT_STR_LOG_PREFIX_(this));
else
} else {
logMessage(this->getServerId(), "[{}] Using unencrypted basic connection.", CLIENT_STR_LOG_PREFIX_(this));
}
}
if(this->ssl_encrypted) {
this->ssl_handler.process_incoming_data(buffer);
this->ssl_handler.process_incoming_data(pipes::buffer_view{buffer.data(), buffer.length()});
} else {
this->ws_handler.process_incoming_data(buffer);
}
if(has_next) {
this->registerMessageProcess();
this->ws_handler.process_incoming_data(pipes::buffer_view{buffer.data(), buffer.length()});
}
return true;
}
+20 -6
View File
@@ -23,7 +23,10 @@ using namespace ts;
using namespace ts::server;
using namespace ts::protocol;
WebClient::WebClient(WebControlServer* server, int fd) : SpeakingClient(server->getTS()->getSql(), server->getTS()), handle(server), whisper_handler_{this} {
WebClient::WebClient(WebControlServer* server, int fd) :
SpeakingClient(server->getTS()->getSql(), server->getTS()),
handle{server},
whisper_handler_{this} {
memtrack::allocated<WebClient>(this);
assert(server->getTS());
@@ -34,7 +37,8 @@ WebClient::WebClient(WebControlServer* server, int fd) : SpeakingClient(server->
}
void WebClient::initialize() {
this->event_handle_packet = make_shared<event::ProxiedEventEntry<WebClient>>(dynamic_pointer_cast<WebClient>(this->ref()), &WebClient::processNextMessage);
auto ref_this = dynamic_pointer_cast<WebClient>(this->ref());
this->command_queue = std::make_unique<ServerCommandQueue>(serverInstance->server_command_executor(), std::make_unique<WebClientCommandHandler>(ref_this));
int enabled = 1;
int disabled = 0;
@@ -176,7 +180,7 @@ void WebClient::sendCommand(const ts::command_builder &command, bool low) {
this->sendJson(value);
} else {
auto data = command.build();
Command parsed_command = Command::parse(pipes::buffer_view{data.data(), data.length()}, true, false);
Command parsed_command = Command::parse(data, true, false);
this->sendCommand(parsed_command, low);
}
}
@@ -221,7 +225,6 @@ bool WebClient::close_connection(const std::chrono::system_clock::time_point& ti
{
lock_guard lock(self_lock->queue_mutex);
flag_flushed &= self_lock->queue_read.empty();
flag_flushed &= self_lock->queue_write.empty();
}
@@ -274,8 +277,8 @@ command_result WebClient::handleCommand(Command &command) {
return SpeakingClient::handleCommand(command);
}
void WebClient::tick(const std::chrono::system_clock::time_point& point) {
SpeakingClient::tick(point);
void WebClient::tick_server(const std::chrono::system_clock::time_point& point) {
SpeakingClient::tick_server(point);
if(this->ping.last_request + seconds(1) < point) {
if(this->ping.last_response > this->ping.last_request || this->ping.last_response + this->ping.timeout < point) {
@@ -420,6 +423,17 @@ void WebClient::disconnectFinal() {
this->handle->unregisterConnection(static_pointer_cast<WebClient>(self_lock));
}
WebClientCommandHandler::WebClientCommandHandler(const std::shared_ptr<WebClient> &client) : client_ref{client} {}
bool WebClientCommandHandler::handle_command(const std::string_view &command) {
auto client = this->client_ref.lock();
if(!client) {
return false;
}
return client->process_next_message(command);
}
Json::CharReaderBuilder json_reader_builder = []() noexcept {
Json::CharReaderBuilder reader_builder;
+18 -6
View File
@@ -11,12 +11,15 @@
#include <json/json.h>
#include <EventLoop.h>
#include "../shared/WhisperHandler.h"
#include "../shared/ServerCommandExecutor.h"
namespace ts::server {
class WebControlServer;
class WebClientCommandHandler;
class WebClient : public SpeakingClient {
friend class WebControlServer;
friend class WebClientCommandHandler;
public:
WebClient(WebControlServer*, int socketFd);
~WebClient() override;
@@ -34,7 +37,7 @@ namespace ts::server {
[[nodiscard]] inline std::chrono::nanoseconds client_ping_layer_7() const { return this->js_ping.value; }
protected:
void tick(const std::chrono::system_clock::time_point&) override; /* Every 500ms */
void tick_server(const std::chrono::system_clock::time_point&) override; /* Every 500ms */
void applySelfLock(const std::shared_ptr<WebClient> &cl){ _this = cl; }
private:
@@ -52,8 +55,6 @@ namespace ts::server {
::event* readEvent;
::event* writeEvent;
std::shared_ptr<event::ProxiedEventEntry<WebClient>> event_handle_packet;
struct {
uint8_t current_id{0};
std::chrono::system_clock::time_point last_request;
@@ -73,7 +74,7 @@ namespace ts::server {
} js_ping;
std::mutex queue_mutex;
std::deque<pipes::buffer> queue_read;
std::unique_ptr<ServerCommandQueue> command_queue{};
std::deque<pipes::buffer> queue_write;
threads::Mutex execute_mutex; /* needs to be recursive! */
@@ -88,8 +89,8 @@ namespace ts::server {
void handleMessageWrite(int, short, void*);
void enqueue_raw_packet(const pipes::buffer_view& /* buffer */);
void processNextMessage(const std::chrono::system_clock::time_point& /* scheduled */);
void registerMessageProcess();
/* TODO: Put the message processing part into the IO loop and not into command processing! */
bool process_next_message(const std::string_view& buffer);
//WS events
void onWSConnected();
@@ -110,5 +111,16 @@ namespace ts::server {
command_result handleCommandWhisperSessionInitialize(Command &command);
command_result handleCommandWhisperSessionReset(Command &command);
};
class WebClientCommandHandler : public ts::server::ServerCommandHandler {
public:
explicit WebClientCommandHandler(const std::shared_ptr<WebClient>& /* client */);
protected:
bool handle_command(const std::string_view &) override;
private:
std::weak_ptr<WebClient> client_ref;
};
}
#endif