mirror of
https://github.com/EvernodeXRPL/hpcore.git
synced 2026-04-29 15:37:59 +00:00
Websocket initial implementation (#9)
* Added listener and session classes. * Added client session class. * Fixed minor code issues. * Initial server implementation p2p connection * Added a seperate thread to run the two servers * Implemented basic web socket architecture * Implemented basic peer to peer socket network * Added a sample message * Initial socket architecture completed * Improved code readability * Improved comments
This commit is contained in:
133
src/sock/socket_session.cpp
Normal file
133
src/sock/socket_session.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#include <iostream>
|
||||
#include <boost/beast/core.hpp>
|
||||
#include <boost/beast/websocket.hpp>
|
||||
#include "socket_session.h"
|
||||
|
||||
namespace net = boost::asio;
|
||||
|
||||
using tcp = net::ip::tcp;
|
||||
using error_code = boost::system::error_code;
|
||||
|
||||
namespace sock
|
||||
{
|
||||
|
||||
socket_session::socket_session(tcp::socket socket, socket_session_handler &sess_handler)
|
||||
: ws_(std::move(socket)), sess_handler_(sess_handler)
|
||||
{
|
||||
}
|
||||
|
||||
void socket_session::server_run(const unsigned short &port, const std::string &address)
|
||||
{
|
||||
port_ = port;
|
||||
address_ = address;
|
||||
|
||||
// Accept the websocket handshake
|
||||
ws_.async_accept(
|
||||
[sp = shared_from_this()](
|
||||
error ec) {
|
||||
sp->on_accept(ec);
|
||||
});
|
||||
}
|
||||
|
||||
void socket_session::client_run(const unsigned short &port, const std::string &address, error ec)
|
||||
{
|
||||
port_ = port;
|
||||
address_ = address;
|
||||
|
||||
sess_handler_.on_connect(this, ec);
|
||||
if (ec)
|
||||
return fail(ec, "handshake");
|
||||
|
||||
ws_.async_read(
|
||||
buffer_,
|
||||
[sp = shared_from_this()](
|
||||
error_code ec, std::size_t bytes) {
|
||||
sp->on_read(ec, bytes);
|
||||
});
|
||||
}
|
||||
|
||||
void socket_session::fail(error_code ec, char const *what)
|
||||
{
|
||||
// Don't report these
|
||||
if (ec == net::error::operation_aborted ||
|
||||
ec == websocket::error::closed)
|
||||
return;
|
||||
|
||||
std::cerr << what << ": " << ec.message() << "\n";
|
||||
}
|
||||
|
||||
void socket_session::on_accept(error_code ec)
|
||||
{
|
||||
sess_handler_.on_connect(this, ec);
|
||||
|
||||
// Handle the error, if any
|
||||
if (ec)
|
||||
return fail(ec, "accept");
|
||||
|
||||
// Read a message
|
||||
ws_.async_read(
|
||||
buffer_,
|
||||
[sp = shared_from_this()](
|
||||
error_code ec, std::size_t bytes) {
|
||||
sp->on_read(ec, bytes);
|
||||
});
|
||||
}
|
||||
|
||||
void socket_session::on_read(error_code ec, std::size_t)
|
||||
{
|
||||
auto const string_message = std::make_shared<std::string const>(std::move(beast::buffers_to_string(buffer_.data())));
|
||||
sess_handler_.on_message(this, string_message, ec);
|
||||
|
||||
// Handle the error, if any
|
||||
if (ec)
|
||||
return fail(ec, "read");
|
||||
|
||||
// Clear the buffer
|
||||
buffer_.consume(buffer_.size());
|
||||
|
||||
// Read another message
|
||||
ws_.async_read(
|
||||
buffer_,
|
||||
[sp = shared_from_this()](
|
||||
error_code ec, std::size_t bytes) {
|
||||
sp->on_read(ec, bytes);
|
||||
});
|
||||
}
|
||||
|
||||
void socket_session::send(std::shared_ptr<std::string const> const &ss)
|
||||
{
|
||||
// Always add to queue
|
||||
queue_.push_back(ss);
|
||||
|
||||
// Are we already writing?
|
||||
if (queue_.size() > 1)
|
||||
return;
|
||||
|
||||
// We are not currently writing, so send this immediately
|
||||
ws_.async_write(
|
||||
net::buffer(*queue_.front()),
|
||||
[sp = shared_from_this()](
|
||||
error_code ec, std::size_t bytes) {
|
||||
sp->on_write(ec, bytes);
|
||||
});
|
||||
}
|
||||
|
||||
void socket_session::on_write(error_code ec, std::size_t)
|
||||
{
|
||||
// Handle the error, if any
|
||||
if (ec)
|
||||
return fail(ec, "write");
|
||||
|
||||
// Remove the string from the queue
|
||||
queue_.erase(queue_.begin());
|
||||
|
||||
// Send the next message if any
|
||||
if (!queue_.empty())
|
||||
ws_.async_write(
|
||||
net::buffer(*queue_.front()),
|
||||
[sp = shared_from_this()](
|
||||
error_code ec, std::size_t bytes) {
|
||||
sp->on_write(ec, bytes);
|
||||
});
|
||||
}
|
||||
} // namespace sock
|
||||
Reference in New Issue
Block a user