Skip to content

Commit 686f68a

Browse files
authored
Add setConnectionCallback (#2204)
1 parent 152a69f commit 686f68a

File tree

10 files changed

+85
-2
lines changed

10 files changed

+85
-2
lines changed

examples/async_stream/main.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
#include <drogon/drogon.h>
22
#include <chrono>
3+
#include <functional>
4+
#include <mutex>
5+
#include <unordered_map>
6+
#include <trantor/utils/Logger.h>
7+
#include <trantor/net/callbacks.h>
8+
#include <trantor/net/TcpConnection.h>
39

410
using namespace drogon;
511
using namespace std::chrono_literals;
612

13+
std::mutex mutex;
14+
std::unordered_map<trantor::TcpConnectionPtr, std::function<void()>>
15+
connMapping;
16+
717
int main()
818
{
919
app().registerHandler(
1020
"/stream",
11-
[](const HttpRequestPtr &,
21+
[](const HttpRequestPtr &req,
1222
std::function<void(const HttpResponsePtr &)> &&callback) {
23+
const auto &weakConnPtr = req->getConnectionPtr();
24+
if (auto connPtr = weakConnPtr.lock())
25+
{
26+
std::lock_guard lk(mutex);
27+
connMapping.emplace(std::move(connPtr), [] {
28+
LOG_INFO << "call stop or other options!!!!";
29+
});
30+
}
1331
auto resp = drogon::HttpResponse::newAsyncStreamResponse(
1432
[](drogon::ResponseStreamPtr stream) {
1533
std::thread([stream =
@@ -79,5 +97,17 @@ int main()
7997

8098
LOG_INFO << "Server running on 127.0.0.1:8848";
8199
app().enableRequestStream(); // This is for request stream.
100+
app().setConnectionCallback([](const trantor::TcpConnectionPtr &conn) {
101+
if (conn->disconnected())
102+
{
103+
std::lock_guard lk(mutex);
104+
if (auto it = connMapping.find(conn); it != connMapping.end())
105+
{
106+
LOG_INFO << "disconnect";
107+
connMapping[conn]();
108+
connMapping.erase(conn);
109+
}
110+
}
111+
});
82112
app().addListener("127.0.0.1", 8848).run();
83113
}

lib/inc/drogon/HttpAppFramework.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,15 @@ class DROGON_EXPORT HttpAppFramework : public trantor::NonCopyable
16151615
virtual HttpAppFramework &setAfterAcceptSockOptCallback(
16161616
std::function<void(int)> cb) = 0;
16171617

1618+
/**
1619+
* @brief Set the client disconnect or connect callback.
1620+
*
1621+
* @param cb This callback will be called, when the client disconnect or
1622+
* connect
1623+
*/
1624+
virtual HttpAppFramework &setConnectionCallback(
1625+
std::function<void(const trantor::TcpConnectionPtr &)> cb) = 0;
1626+
16181627
virtual HttpAppFramework &enableRequestStream(bool enable = true) = 0;
16191628
virtual bool isRequestStreamEnabled() const = 0;
16201629

lib/inc/drogon/HttpRequest.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <unordered_map>
3131
#include <optional>
3232
#include <string_view>
33+
#include <trantor/net/TcpConnection.h>
3334

3435
namespace drogon
3536
{
@@ -506,6 +507,9 @@ class DROGON_EXPORT HttpRequest
506507

507508
virtual bool connected() const noexcept = 0;
508509

510+
virtual const std::weak_ptr<trantor::TcpConnection> &getConnectionPtr()
511+
const noexcept = 0;
512+
509513
virtual ~HttpRequest()
510514
{
511515
}

lib/src/HttpAppFrameworkImpl.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,3 +1367,10 @@ HttpAppFramework &HttpAppFrameworkImpl::setAfterAcceptSockOptCallback(
13671367
listenerManagerPtr_->setAfterAcceptSockOptCallback(std::move(cb));
13681368
return *this;
13691369
}
1370+
1371+
HttpAppFramework &HttpAppFrameworkImpl::setConnectionCallback(
1372+
std::function<void(const trantor::TcpConnectionPtr &)> cb)
1373+
{
1374+
listenerManagerPtr_->setConnectionCallback(std::move(cb));
1375+
return *this;
1376+
}

lib/src/HttpAppFrameworkImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,8 @@ class HttpAppFrameworkImpl final : public HttpAppFramework
665665
std::function<void(int)> cb) override;
666666
HttpAppFramework &setAfterAcceptSockOptCallback(
667667
std::function<void(int)> cb) override;
668+
HttpAppFramework &setConnectionCallback(
669+
std::function<void(const trantor::TcpConnectionPtr &)> cb) override;
668670

669671
HttpAppFramework &enableRequestStream(bool enable) override;
670672
bool isRequestStreamEnabled() const override;

lib/src/HttpRequestImpl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "HttpUtils.h"
1818
#include "CacheFile.h"
19+
#include "impl_forwards.h"
1920
#include <drogon/utils/Utilities.h>
2021
#include <drogon/HttpRequest.h>
2122
#include <drogon/RequestStream.h>
@@ -572,6 +573,12 @@ class HttpRequestImpl : public HttpRequest
572573
return false;
573574
}
574575

576+
const std::weak_ptr<trantor::TcpConnection> &getConnectionPtr()
577+
const noexcept override
578+
{
579+
return connPtr_;
580+
}
581+
575582
bool isOnSecureConnection() const noexcept override
576583
{
577584
return isOnSecureConnection_;

lib/src/HttpServer.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "HttpControllersRouter.h"
3131
#include "StaticFileRouter.h"
3232
#include "WebSocketConnectionImpl.h"
33+
#include "impl_forwards.h"
3334

3435
#if COZ_PROFILING
3536
#include <coz.h>
@@ -75,7 +76,12 @@ HttpServer::HttpServer(EventLoop *loop,
7576
: server_(loop, listenAddr, std::move(name), true, app().reusePort())
7677
#endif
7778
{
78-
server_.setConnectionCallback(onConnection);
79+
server_.setConnectionCallback(
80+
[this](const trantor::TcpConnectionPtr &conn) {
81+
onConnection(conn);
82+
if (connectionCallback_)
83+
connectionCallback_(conn);
84+
});
7985
server_.setRecvMessageCallback(onMessage);
8086
server_.kickoffIdleConnections(
8187
HttpAppFrameworkImpl::instance().getIdleConnectionTimeout());

lib/src/HttpServer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ class HttpServer : trantor::NonCopyable
6969
afterAcceptSetSockOptCallback_ = std::move(cb);
7070
}
7171

72+
void setConnectionCallback(
73+
std::function<void(const trantor::TcpConnectionPtr &)> cb)
74+
{
75+
connectionCallback_ = std::move(cb);
76+
}
77+
7278
private:
7379
friend class HttpInternalForwardHelper;
7480

@@ -144,6 +150,7 @@ class HttpServer : trantor::NonCopyable
144150

145151
std::function<void(int)> beforeListenSetSockOptCallback_;
146152
std::function<void(int)> afterAcceptSetSockOptCallback_;
153+
std::function<void(const trantor::TcpConnectionPtr &)> connectionCallback_;
147154
};
148155

149156
class HttpInternalForwardHelper

lib/src/ListenerManager.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ void ListenerManager::createListeners(
121121
serverPtr->setAfterAcceptSockOptCallback(
122122
afterAcceptSetSockOptCallback_);
123123
}
124+
if (connectionCallback_)
125+
{
126+
serverPtr->setConnectionCallback(connectionCallback_);
127+
}
124128

125129
if (listener.useSSL_ && utils::supportsTls())
126130
{

lib/src/ListenerManager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ class ListenerManager : public trantor::NonCopyable
6161
afterAcceptSetSockOptCallback_ = std::move(cb);
6262
}
6363

64+
void setConnectionCallback(
65+
std::function<void(const trantor::TcpConnectionPtr &)> cb)
66+
{
67+
connectionCallback_ = std::move(cb);
68+
}
69+
6470
void reloadSSLFiles();
6571

6672
private:
@@ -101,6 +107,7 @@ class ListenerManager : public trantor::NonCopyable
101107
std::unique_ptr<trantor::EventLoopThread> listeningThread_;
102108
std::function<void(int)> beforeListenSetSockOptCallback_;
103109
std::function<void(int)> afterAcceptSetSockOptCallback_;
110+
std::function<void(const trantor::TcpConnectionPtr &)> connectionCallback_;
104111
};
105112

106113
} // namespace drogon

0 commit comments

Comments
 (0)