8#include "protocolhttp.h"
12#include <Cutelyst/Engine>
15#include <QLoggingCategory>
17Q_LOGGING_CATEGORY(C_SERVER_TCP,
"cutelyst.server.tcp", QtWarningMsg)
21TcpServer::TcpServer(
const QByteArray &serverAddress,
26 , m_serverAddress(serverAddress)
28 , m_protocol(protocol)
30 m_engine = qobject_cast<ServerEngine *>(parent);
32 if (m_server->tcpNodelay()) {
33 m_socketOptions.emplace_back(QAbstractSocket::LowDelayOption, 1);
35 if (m_server->soKeepalive()) {
36 m_socketOptions.emplace_back(QAbstractSocket::KeepAliveOption, 1);
38 if (m_server->socketSndbuf() != -1) {
39 m_socketOptions.emplace_back(QAbstractSocket::SendBufferSizeSocketOption,
40 m_server->socketSndbuf());
42 if (m_server->socketRcvbuf() != -1) {
43 m_socketOptions.emplace_back(QAbstractSocket::ReceiveBufferSizeSocketOption,
44 m_server->socketRcvbuf());
48void TcpServer::incomingConnection(qintptr handle)
50 auto sock =
new TcpSocket(m_engine,
this);
51 sock->serverAddress = m_serverAddress;
52 sock->protoData = m_protocol->createData(sock);
54 connect(sock, &QIODevice::readyRead, [sock] {
55 sock->timeout =
false;
56 sock->proto->parse(sock, sock);
58 connect(sock, &TcpSocket::finished,
this, [
this, sock] {
60 if (--m_processing == 0) {
61 m_engine->stopSocketTimeout();
65 if (Q_LIKELY(sock->setSocketDescriptor(
66 handle, QTcpSocket::ConnectedState, QTcpSocket::ReadWrite | QTcpSocket::Unbuffered))) {
67 sock->proto = m_protocol;
69 sock->remoteAddress = sock->peerAddress();
70 sock->remotePort = sock->peerPort();
71 sock->protoData->setupNewConnection(sock);
73 for (
const auto &opt : m_socketOptions) {
74 sock->setSocketOption(opt.first, opt.second);
78 m_engine->startSocketTimeout();
85void TcpServer::shutdown()
89 if (m_processing == 0) {
90 m_engine->serverShutdown();
92 const auto childrenL = children();
93 for (
auto child : childrenL) {
94 auto socket = qobject_cast<TcpSocket *>(child);
96 connect(socket, &TcpSocket::finished,
this, [
this]() {
97 if (m_processing == 0) {
98 m_engine->serverShutdown();
101 m_engine->handleSocketShutdown(socket);
107void TcpServer::timeoutConnections()
110 const auto childrenL = children();
111 for (
auto child : childrenL) {
112 auto socket = qobject_cast<TcpSocket *>(child);
113 if (socket && !socket->processing &&
114 socket->state() == QAbstractSocket::ConnectedState) {
115 if (socket->timeout) {
116 qCInfo(C_SERVER_TCP) <<
"timing out connection"
117 << socket->peerAddress().toString() << socket->peerPort();
118 socket->connectionClose();
120 socket->timeout =
true;
127Protocol *TcpServer::protocol()
const
132void TcpServer::setProtocol(
Protocol *protocol)
134 m_protocol = protocol;
137#include "moc_tcpserver.cpp"
The Cutelyst namespace holds all public Cutelyst API.