104 lines
2.4 KiB
C++
104 lines
2.4 KiB
C++
/*
|
||
* tcp_connection.cpp
|
||
*
|
||
* Created on: 20 сент. 2022 г.
|
||
* Author: alexander
|
||
*/
|
||
|
||
#include <connection/tcp_connection.hpp>
|
||
#include <iostream>
|
||
|
||
namespace azh
|
||
{
|
||
TCPConnection::TCPConnection(io::ip::tcp::socket&& socket) : _socket(std::move(socket))
|
||
{
|
||
boost::system::error_code ec;
|
||
|
||
std::stringstream name;
|
||
name << _socket.remote_endpoint();
|
||
|
||
_username = name.str();
|
||
}
|
||
|
||
tcp::socket& TCPConnection::socket()
|
||
{
|
||
return _socket;
|
||
}
|
||
|
||
void TCPConnection::start(MessageHandler&& messageHandler, ErrorHandler&& errorHandler)
|
||
{
|
||
_messageHandler = std::move(messageHandler);
|
||
_errorHandler = std::move(errorHandler);
|
||
|
||
asyncRead();
|
||
}
|
||
|
||
void TCPConnection::post(const std::string& message)
|
||
{
|
||
bool queueIdle = _outgoingMessages.empty();
|
||
_outgoingMessages.push(message);
|
||
|
||
if (queueIdle)
|
||
asyncWrite();
|
||
}
|
||
|
||
void TCPConnection::asyncRead()
|
||
{
|
||
io::async_read_until(_socket, _streamBuf, '\n', [self = shared_from_this()]
|
||
(boost::system::error_code ec, size_t bytesTransferred) {
|
||
self->onRead(ec, bytesTransferred);
|
||
});
|
||
}
|
||
|
||
void TCPConnection::onRead(boost::system::error_code &ec, size_t bytesTransferred)
|
||
{
|
||
if (ec)
|
||
{
|
||
_socket.close(ec);
|
||
|
||
_errorHandler();
|
||
|
||
return;
|
||
}
|
||
|
||
std::stringstream message;
|
||
message << _username << ": " << std::istream(&_streamBuf).rdbuf();
|
||
|
||
_streamBuf.consume(bytesTransferred);
|
||
|
||
_messageHandler(message.str());
|
||
|
||
asyncRead();
|
||
}
|
||
|
||
void TCPConnection::asyncWrite()
|
||
{
|
||
io::async_write(_socket, io::buffer(_outgoingMessages.front()), [self = shared_from_this()]
|
||
(boost::system::error_code ec, size_t bytesTransferred) {
|
||
self->onWrite(ec, bytesTransferred);
|
||
});
|
||
}
|
||
|
||
void TCPConnection::onWrite(boost::system::error_code &ec, size_t bytesTransferred)
|
||
{
|
||
if (ec)
|
||
{
|
||
_socket.close(ec);
|
||
|
||
_errorHandler();
|
||
|
||
return;
|
||
}
|
||
|
||
_outgoingMessages.pop();
|
||
|
||
if (!_outgoingMessages.empty())
|
||
asyncWrite();
|
||
}
|
||
|
||
TCPConnection::Pointer TCPConnection::create(io::ip::tcp::socket&& socket)
|
||
{
|
||
return Pointer(new TCPConnection(std::move(socket)));
|
||
}
|
||
}
|