FeatherMC/src/network/TCPListener.cpp

80 lines
1.9 KiB
C++

#include "TCPListener.h"
#include "TCPSocket.h"
#include "TCPClient.h"
#include "IListenerInterface.h"
#include "logging/Logger.h"
namespace Feather::Network
{
TCPListener::TCPListener(uint16_t port, IListenerInterface* callbacks)
: m_callbacks(callbacks)
{
// Setup the listen socket.
auto socket = std::make_unique<TCPSocket>();
if (!socket->IsValid())
{
Log::Error("Socket failed to be created.");
return;
}
if (!socket->MarkReusable())
{
Log::Error("Failed to mark socket as resuable.");
return;
}
if (socket->IsIPV6() && !socket->MarkDualBind())
{
Log::Error("Failed to mark IPv6 socket as dual-bind.");
return;
}
if (!socket->Bind(port))
{
Log::Error("Failed to bind socket to port {}.", port);
return;
}
if (!socket->MarkNonBlocking())
{
Log::Error("Failed to mark socket as non-blocking.");
return;
}
auto ListenerCallback = [](evconnlistener* evListener, SocketHandle socket, sockaddr* addr, int len, void* self)
{
TCPListener* listener = static_cast<TCPListener*>(self);
listener->OnClientConnect(std::make_unique<TCPClient>(listener, socket, addr));
};
if (!socket->Listen(ListenerCallback, this))
{
Log::Error("Failed to start listening on socket.");
return;
}
m_socket = std::move(socket);
}
TCPListener::~TCPListener()
{
}
bool TCPListener::IsValid() const
{
return m_socket != nullptr;
}
void TCPListener::OnClientConnect(TCPClientHandle&& client)
{
m_callbacks->OnClientConnect(std::move(client));
}
void TCPListener::OnClientDisconnected(const TCPClient* client)
{
m_callbacks->OnClientDisconnect(client);
}
}