Skip to content

Commit cf57512

Browse files
authored
Merge pull request #167 from qicosmos/check_port
2 parents d79aa49 + e10cd5e commit cf57512

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

include/rest_rpc/rpc_server.h

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ class rpc_server : private asio::noncopyable {
1717
public:
1818
rpc_server(unsigned short port, size_t size, size_t timeout_seconds = 15,
1919
size_t check_seconds = 10)
20-
: io_service_pool_(size), acceptor_(io_service_pool_.get_io_service(),
21-
tcp::endpoint(tcp::v4(), port)),
20+
: io_service_pool_(size), acceptor_(io_service_pool_.get_io_service()),
2221
timeout_seconds_(timeout_seconds), check_seconds_(check_seconds),
23-
signals_(io_service_pool_.get_io_service()) {
24-
do_accept();
22+
signals_(io_service_pool_.get_io_service()),
23+
port_(std::to_string(port)) {
2524
check_thread_ = std::make_shared<std::thread>([this] { clean(); });
2625
pub_sub_thread_ =
2726
std::make_shared<std::thread>([this] { clean_sub_pub(); });
@@ -33,6 +32,12 @@ class rpc_server : private asio::noncopyable {
3332
do_await_stop();
3433
}
3534

35+
rpc_server(std::string address, unsigned short port, size_t size,
36+
size_t timeout_seconds = 15, size_t check_seconds = 10)
37+
: rpc_server(port, size, timeout_seconds, check_seconds) {
38+
address_ = std::move(address);
39+
}
40+
3641
rpc_server(unsigned short port, size_t size, ssl_configure ssl_conf,
3742
size_t timeout_seconds = 15, size_t check_seconds = 10)
3843
: rpc_server(port, size, timeout_seconds, check_seconds) {
@@ -46,11 +51,24 @@ class rpc_server : private asio::noncopyable {
4651

4752
~rpc_server() { stop(); }
4853

49-
void async_run() {
50-
thd_ = std::make_shared<std::thread>([this] { io_service_pool_.run(); });
54+
std::error_code async_run() {
55+
auto ec = listen();
56+
if (!ec) {
57+
do_accept();
58+
thd_ = std::make_shared<std::thread>([this] { io_service_pool_.run(); });
59+
}
60+
return ec;
5161
}
5262

53-
void run() { io_service_pool_.run(); }
63+
std::error_code run() {
64+
auto ec = listen();
65+
if (!ec) {
66+
do_accept();
67+
io_service_pool_.run();
68+
}
69+
70+
return ec;
71+
}
5472

5573
template <bool is_pub = false, typename Function>
5674
void register_handler(std::string const &name, const Function &f) {
@@ -132,6 +150,50 @@ class rpc_server : private asio::noncopyable {
132150
});
133151
}
134152

153+
std::error_code listen() {
154+
using asio::ip::tcp;
155+
asio::error_code ec;
156+
asio::ip::tcp::resolver resolver(acceptor_.get_executor());
157+
auto endpoints = resolver.resolve(address_, port_, ec);
158+
if (ec) {
159+
return ec;
160+
}
161+
162+
auto it = endpoints.begin();
163+
164+
if (it == endpoints.end()) {
165+
return std::make_error_code(std::errc::bad_address);
166+
}
167+
168+
auto endpoint = it->endpoint();
169+
acceptor_.open(endpoint.protocol(), ec);
170+
if (ec) {
171+
return ec;
172+
}
173+
174+
#ifdef __GNUC__
175+
acceptor_.set_option(tcp::acceptor::reuse_address(true), ec);
176+
#endif
177+
acceptor_.bind(endpoint, ec);
178+
if (ec) {
179+
std::error_code ignore;
180+
acceptor_.cancel(ignore);
181+
acceptor_.close(ignore);
182+
return ec;
183+
}
184+
#ifdef _MSC_VER
185+
acceptor_.set_option(tcp::acceptor::reuse_address(true));
186+
#endif
187+
acceptor_.listen(asio::socket_base::max_listen_connections, ec);
188+
if (ec) {
189+
std::error_code ignore;
190+
acceptor_.cancel(ignore);
191+
acceptor_.close(ignore);
192+
return ec;
193+
}
194+
return ec;
195+
}
196+
135197
void clean() {
136198
while (!stop_check_) {
137199
std::unique_lock<std::mutex> lock(mtx_);
@@ -259,6 +321,8 @@ class rpc_server : private asio::noncopyable {
259321
std::shared_ptr<connection> conn_;
260322
std::shared_ptr<std::thread> thd_;
261323
std::size_t timeout_seconds_;
324+
std::string address_ = "0.0.0.0";
325+
std::string port_ = "";
262326

263327
std::unordered_map<int64_t, std::shared_ptr<connection>> connections_;
264328
int64_t conn_id_ = 0;

tests/test_rest_rpc.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,31 @@ TEST_CASE("test_client_default_constructor") {
109109
CHECK_EQ(result, 3);
110110
}
111111

112+
TEST_CASE("test start some servers with same port") {
113+
rpc_server server1(9000, 1);
114+
rpc_server server2(9000, 1);
115+
auto ec1 = server1.async_run();
116+
CHECK(ec1 == std::error_code{});
117+
auto ec2 = server2.async_run();
118+
CHECK(ec2);
119+
std::cout << ec2.message() << "\n";
120+
rpc_server server3(9000, 1);
121+
auto ec3 = server3.async_run();
122+
CHECK(ec3);
123+
std::cout << ec3.message() << "\n";
124+
}
125+
126+
TEST_CASE("test start server with local ip") {
127+
rpc_server server1("0.0.0.0", 9000, 1);
128+
auto ec1 = server1.async_run();
129+
CHECK(ec1 == std::error_code{});
130+
131+
rpc_server server2("11.11.11.11", 9000, 1);
132+
auto ec2 = server2.async_run();
133+
CHECK(ec2);
134+
std::cout << ec2.message() << "\n"; // address not available
135+
}
136+
112137
TEST_CASE("test_constructor_with_language") {
113138
rpc_server server(9000, std::thread::hardware_concurrency());
114139
dummy d;

0 commit comments

Comments
 (0)