unilink  0.4.3
A simple C++ library for unified async communication
tcp_server_builder.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2025 Jinwoo Sung
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <stdexcept>
20 
24 
25 namespace unilink {
26 namespace builder {
27 
29  : port_(port),
30  auto_manage_(false),
31  use_independent_context_(false),
32  enable_port_retry_(false),
33  max_port_retries_(3),
34  port_retry_interval_ms_(1000),
35  idle_timeout_ms_(0),
36  max_clients_(0),
37  client_limit_set_(false) {
38  if (port == 0) throw diagnostics::BuilderException("Invalid port number: 0");
39 
40  // Ensure background IO service is running
42 }
43 
44 std::unique_ptr<wrapper::TcpServer> TcpServerBuilder::build() {
45  std::unique_ptr<wrapper::TcpServer> server;
46  if (use_independent_context_) {
47  server = std::make_unique<wrapper::TcpServer>(port_, std::make_shared<boost::asio::io_context>());
48  server->set_manage_external_context(true);
49  } else {
50  server = std::make_unique<wrapper::TcpServer>(port_);
51  }
52 
53  if (on_data_) server->on_data(on_data_);
54  if (on_connect_) server->on_client_connect(on_connect_);
55  if (on_disconnect_) server->on_client_disconnect(on_disconnect_);
56  if (on_error_) server->on_error(on_error_);
57 
58  if (enable_port_retry_) {
59  server->enable_port_retry(true, max_port_retries_, port_retry_interval_ms_);
60  }
61 
62  if (idle_timeout_ms_ > 0) {
63  server->idle_timeout(idle_timeout_ms_);
64  }
65 
66  if (client_limit_set_) {
67  if (max_clients_ == 0)
68  server->set_unlimited_clients();
69  else
70  server->set_client_limit(max_clients_);
71  }
72 
73  if (auto_manage_) {
74  server->auto_manage(true);
75  }
76 
77  return server;
78 }
79 
81  auto_manage_ = auto_manage;
82  return *this;
83 }
84 
86  on_data_ = std::move(handler);
87  return *this;
88 }
89 
91  on_connect_ = std::move(handler);
92  return *this;
93 }
94 
96  on_disconnect_ = std::move(handler);
97  return *this;
98 }
99 
101  on_error_ = std::move(handler);
102  return *this;
103 }
104 
106  use_independent_context_ = use_independent;
107  return *this;
108 }
109 
110 TcpServerBuilder& TcpServerBuilder::enable_port_retry(bool enable, int max_retries, int retry_interval_ms) {
111  enable_port_retry_ = enable;
112  max_port_retries_ = max_retries;
113  port_retry_interval_ms_ = retry_interval_ms;
114  return *this;
115 }
116 
118  idle_timeout_ms_ = timeout_ms;
119  return *this;
120 }
121 
123  if (max == 0) throw std::invalid_argument("Client limit cannot be 0");
124  if (max == 1) throw std::invalid_argument("Use single_client() for 1 client limit");
125  max_clients_ = max;
126  client_limit_set_ = true;
127  return *this;
128 }
129 
131  max_clients_ = 1; // Simplified: actually handled by TcpServer's set_client_limit(1)
132  client_limit_set_ = true;
133  return *this;
134 }
135 
137 
139  max_clients_ = 0;
140  client_limit_set_ = true;
141  return *this;
142 }
143 
144 } // namespace builder
145 } // namespace unilink