This repository has been archived on 2021-04-23. You can view files and clone it, but cannot push or open issues or pull requests.
brainlet-client/websocket.h
2021-03-25 19:59:07 -04:00

102 lines
3.7 KiB
C++

// Copyright (c) 2021 hiimgoodpack
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef WEBSOCKET_H
#define WEBSOCKET_H
#include <string>
#include <functional>
#include <stdexcept>
// We're doing some declarations instead of just including all of websocketpp since
// websocketpp takes a long time to compile
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
class WebSocketError : public std::runtime_error {
public:
using runtime_error::runtime_error;
};
class WebSocket : public websocketpp::lib::asio::io_service {
private:
websocketpp::client<websocketpp::config::asio_client> client;
websocketpp::connection_hdl hdl;
static void onConnectHandler(WebSocket*, websocketpp::connection_hdl);
static void onReceiveHandler(WebSocket*, websocketpp::config::asio_client::message_type::ptr);
static void onCloseHandler(WebSocket*);
public:
WebSocket(const std::string& url);
void send(std::string buffer);
void close();
std::function<void()> onConnect = nullptr;
std::function<void(std::string)> onReceive = nullptr;
std::function<void()> onClose = nullptr;
};
#endif
#if defined(WEBSOCKET_IMPLEMENTATION) && !defined(WEBSOCKET_IMPLEMENTED)
#define WEBSOCKET_IMPLEMENTED
#include <websocketpp/client.hpp>
#include <iostream>
WebSocket::WebSocket(const std::string& url) {
client.clear_access_channels(websocketpp::log::alevel::all);
client.clear_error_channels(websocketpp::log::elevel::all);
client.init_asio(reinterpret_cast<websocketpp::lib::asio::io_service*>(this));
client.set_open_handler(std::bind(onConnectHandler, this, std::placeholders::_1));
client.set_message_handler(std::bind(onReceiveHandler, this, std::placeholders::_2));
client.set_close_handler(std::bind(onCloseHandler, this));
websocketpp::lib::error_code error;
decltype(client)::connection_ptr connection = client.get_connection(url, error);
if (error)
throw WebSocketError(error.message());
client.connect(connection);
}
void WebSocket::onConnectHandler(WebSocket* socket, websocketpp::connection_hdl hdl) {
socket->hdl = hdl;
if (socket->onConnect)
socket->onConnect();
}
void WebSocket::onReceiveHandler(WebSocket* socket, websocketpp::config::asio_client::message_type::ptr message) {
std::cerr << "Received: " << message->get_payload() << "\n";
if (socket->onReceive)
socket->onReceive(message->get_payload());
}
void WebSocket::onCloseHandler(WebSocket* socket) {
if (socket->onClose)
socket->onClose();
}
void WebSocket::send(std::string buffer) {
std::cerr << "Sending: " << buffer << "\n";
client.send(hdl, buffer, websocketpp::frame::opcode::text);
}
void WebSocket::close() {
client.close(hdl, websocketpp::close::status::going_away, "");
}
#endif