55#include " Request.hpp"
66#include " Response.hpp"
77#include " macros.hpp"
8+ #include < cerrno>
9+ #include < cstring>
810#include < future>
911#include < iostream>
1012
@@ -13,15 +15,15 @@ namespace opserver {
1315namespace jsi = facebook::jsi;
1416namespace react = facebook::react;
1517
16- Server::Server (jsi::Runtime &rt, const std::shared_ptr<react::CallInvoker>& invoker) {
18+ Server::Server (jsi::Runtime &rt,
19+ const std::shared_ptr<react::CallInvoker> &invoker) {
1720 function_map[" callback" ] = HFN2 (this , invoker) {
1821 const std::string method = args[0 ].asString (rt).utf8 (rt);
1922 const std::string path = args[1 ].asString (rt).utf8 (rt);
2023 auto callback = std::make_shared<jsi::Value>(rt, args[2 ]);
2124
22- auto handleRequest = [invoker,
23- callback](const httplib::Request &req,
24- httplib::Response &res) {
25+ auto handleRequest = [invoker, callback](const httplib::Request &req,
26+ httplib::Response &res) {
2527 auto responseDone = std::make_shared<std::promise<void >>();
2628 auto responseFuture = responseDone->get_future ();
2729
@@ -117,16 +119,37 @@ Server::Server(jsi::Runtime &rt, const std::shared_ptr<react::CallInvoker>& invo
117119 if (count > 0 && args[0 ].isNumber ()) {
118120 port = static_cast <int >(args[0 ].asNumber ());
119121 }
120- std::thread ([this , port]() { server.listen (" 0.0.0.0" , port); }).detach ();
121- return {};
122+
123+ if (listen_thread.joinable ()) {
124+ throw std::runtime_error (" [op-server] Server is already listening" );
125+ }
126+
127+ const int bound_port = server.bind_to_port (" 0.0.0.0" , port);
128+ if (bound_port < 0 ) {
129+ const std::string err = std::strerror (errno);
130+ throw std::runtime_error (" [op-server] Failed to bind server to 0.0.0.0:" +
131+ std::to_string (port) + " (" + err + " )" );
132+ }
133+
134+ listen_thread = std::thread ([this ]() {
135+ const bool ok = server.listen_after_bind ();
136+ if (!ok) {
137+ std::cerr << " [op-server] Server stopped unexpectedly while listening"
138+ << std::endl;
139+ }
140+ });
141+
142+ return jsi::Value (bound_port);
122143 });
123144
124145 function_map[" stop" ] = HFN (this ) {
125- server. stop ();
146+ stop ();
126147 return {};
127148 });
128149}
129150
151+ Server::~Server () { stop (); }
152+
130153std::vector<jsi::PropNameID> Server::getPropertyNames (jsi::Runtime &_rt) {
131154 std::vector<jsi::PropNameID> keys;
132155 keys.reserve (function_map.size ());
@@ -148,7 +171,12 @@ jsi::Value Server::get(jsi::Runtime &rt, const jsi::PropNameID &propNameID) {
148171 return {rt, function_map[name]};
149172}
150173
151- void Server::stop () { server.stop (); }
174+ void Server::stop () {
175+ server.stop ();
176+ if (listen_thread.joinable ()) {
177+ listen_thread.join ();
178+ }
179+ }
152180
153181} // namespace opserver
154182
0 commit comments