#include "asio_service.h"
#include "threads/thread.h"
#include <atomic>
#include <iostream>
{
public:
void DisconnectAndStop()
{
_stop = true;
CppCommon::Thread::Yield();
}
protected:
{
request.
SetHeader(
"Origin",
"https://localhost");
request.
SetHeader(
"Sec-WebSocket-Key", CppCommon::Encoding::Base64Encode(
ws_nonce()));
request.
SetHeader(
"Sec-WebSocket-Protocol",
"chat, superchat");
request.
SetHeader(
"Sec-WebSocket-Version",
"13");
}
{
std::cout <<
"Chat WebSocket secure client connected a new session with Id " <<
id() << std::endl;
}
{
std::cout <<
"Chat WebSocket secure client disconnected a session with Id " <<
id() << std::endl;
}
{
std::cout << "Incoming: " << std::string((const char*)buffer, size) << std::endl;
}
{
CppCommon::Thread::Sleep(1000);
if (!_stop)
}
void onError(
int error,
const std::string& category,
const std::string& message)
override
{
std::cout << "Chat WebSocket secure client caught an error with code " << error << " and category '" << category << "': " << message << std::endl;
}
private:
std::atomic<bool> _stop{false};
};
int main(int argc, char** argv)
{
std::string address = "127.0.0.1";
if (argc > 1)
address = argv[1];
int port = 8443;
if (argc > 2)
port = std::atoi(argv[2]);
std::cout << "WebSocket secure server address: " << address << std::endl;
std::cout << "WebSocket secure server port: " << port << std::endl;
std::cout << std::endl;
auto service = std::make_shared<AsioService>();
std::cout << "Asio service starting...";
service->Start();
std::cout << "Done!" << std::endl;
auto context = std::make_shared<CppServer::Asio::SSLContext>(asio::ssl::context::tlsv13);
context->set_default_verify_paths();
context->set_root_certs();
context->set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert);
context->load_verify_file("../tools/certificates/ca.pem");
auto client = std::make_shared<ChatClient>(service, context, address, port);
std::cout << "Client connecting...";
client->ConnectAsync();
std::cout << "Done!" << std::endl;
std::cout << "Press Enter to stop the client or '!' to reconnect the client..." << std::endl;
std::string line;
while (getline(std::cin, line))
{
if (line.empty())
break;
if (line == "!")
{
std::cout << "Client reconnecting...";
client->IsConnected() ? client->ReconnectAsync() : client->ConnectAsync();
std::cout << "Done!" << std::endl;
continue;
}
client->SendTextAsync(line);
}
std::cout << "Client disconnecting...";
client->DisconnectAndStop();
std::cout << "Done!" << std::endl;
std::cout << "Asio service stopping...";
service->Stop();
std::cout << "Done!" << std::endl;
return 0;
}
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
bool IsConnected() const noexcept
Is the client connected?
const CppCommon::UUID & id() const noexcept
Get the client Id.
HTTPRequest & SetBegin(std::string_view method, std::string_view url, std::string_view protocol="HTTP/1.1")
Set the HTTP request begin with a given method, URL and protocol.
HTTPRequest & SetHeader(std::string_view key, std::string_view value)
Set the HTTP request header.
virtual bool CloseAsync()
bool ConnectAsync() override
Connect the client (asynchronous)
void onDisconnected() override
Handle client disconnected notification.
WSSClient(const WSSClient &)=delete
std::string_view ws_nonce() const noexcept
Get the WebSocket random nonce.
virtual void onWSConnecting(HTTP::HTTPRequest &request)
Handle WebSocket client connecting notification.
virtual void onWSReceived(const void *buffer, size_t size)
Handle WebSocket received notification.
virtual void onWSConnected(const HTTP::HTTPResponse &response)
Handle WebSocket client connected notification.
virtual void onWSDisconnected()
Handle WebSocket client disconnected notification.
WebSocket secure client definition.