geekbrains_network_programming/lesson_04/connection/tcp_connection.cpp

104 lines
2.4 KiB
C++
Raw Normal View History

2022-09-21 13:04:06 +00:00
/*
* 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)));
}
}