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)));
|
|||
|
}
|
|||
|
}
|