Skip to content
This repository was archived by the owner on Aug 2, 2020. It is now read-only.

Commit 0c5d992

Browse files
committed
Detail fix
1 parent 46e29f8 commit 0c5d992

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

src/api/server_class.cpp

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "types.h"
2727
#include "utils/params_class.h"
28+
#include "web_server/utility.hpp"
2829

2930
using namespace std;
3031
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
@@ -37,7 +38,11 @@ extern ApiHandlerMap api_handlers; // defined in handlers.cpp
3738

3839
static const auto TAG = u8"API服务";
3940

40-
static bool authorize(const decltype(HttpServer::Request::header) &headers, const json &query_args,
41+
/**
42+
* Do authorization (check access token),
43+
* should be called on incomming connection request (http server and websocket server)
44+
*/
45+
static bool authorize(const SimpleWeb::CaseInsensitiveMultimap &headers, const json &query_args,
4146
const function<void(SimpleWeb::StatusCode)> on_failed = nullptr) {
4247
if (config.access_token.empty()) {
4348
return true;
@@ -90,7 +95,9 @@ void ApiServer::init() {
9095
}
9196

9297
void ApiServer::init_http() {
98+
// recreate http server instance
9399
http_server_ = make_shared<HttpServer>();
100+
94101
http_server_->default_resource["GET"]
95102
= http_server_->default_resource["POST"]
96103
= [](shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request) {
@@ -160,7 +167,7 @@ void ApiServer::init_http() {
160167
Log::d(TAG, u8"API 处理函数 " + handler_kv.first + u8" 开始处理请求");
161168
ApiResult result;
162169
Params params(json_params);
163-
handler_kv.second(params, result);
170+
handler_kv.second(params, result); // call the real handler
164171

165172
decltype(request->header) headers{
166173
{"Content-Type", "application/json; charset=UTF-8"}
@@ -173,6 +180,7 @@ void ApiServer::init_http() {
173180
};
174181
}
175182

183+
// data files handler
176184
const auto regex = "^/(data/(?:bface|image|record|show)/.+)$";
177185
http_server_->resource[regex]["GET"] = [](shared_ptr<HttpServer::Response> response,
178186
shared_ptr<HttpServer::Request> request) {
@@ -220,8 +228,13 @@ void ApiServer::init_http() {
220228
};
221229
}
222230

223-
template <typename Ws>
224-
static void api_on_message(shared_ptr<typename Ws::Connection> connection, shared_ptr<typename Ws::Message> message) {
231+
/**
232+
* \brief Common "on_message" callback for websocket server's api endpoint and reverse websocket api client.
233+
* \tparam WsT WsServer (websocket server /api/ endpoint) or WsClient (reverse websocket api client)
234+
*/
235+
template <typename WsT>
236+
static void ws_api_on_message(shared_ptr<typename WsT::Connection> connection,
237+
shared_ptr<typename WsT::Message> message) {
225238
auto ws_message_str = message->string();
226239
Log::d(TAG, u8"收到 API 请求(WebSocket):" + ws_message_str);
227240

@@ -230,7 +243,7 @@ static void api_on_message(shared_ptr<typename Ws::Connection> connection, share
230243
auto send_result = [&]() {
231244
auto resp_body = result.json().dump();
232245
Log::d(TAG, u8"响应数据已准备完毕:" + resp_body);
233-
auto send_stream = make_shared<typename Ws::SendStream>();
246+
auto send_stream = make_shared<typename WsT::SendStream>();
234247
*send_stream << resp_body;
235248
connection->send(send_stream);
236249
Log::d(TAG, u8"响应内容已发送");
@@ -291,12 +304,18 @@ void ApiServer::init_ws() {
291304

292305
auto &api_endpoint = ws_server_->endpoint["^/api/?$"];
293306
api_endpoint.on_open = on_open_callback;
294-
api_endpoint.on_message = api_on_message<WsServer>;
307+
api_endpoint.on_message = ws_api_on_message<WsServer>;
295308

296309
auto &event_endpoint = ws_server_->endpoint["^/event/?$"];
297310
event_endpoint.on_open = on_open_callback;
298311
}
299312

313+
/**
314+
* \brief Set some common headers like "User-Agent" and "Authorization"
315+
* for reverse websocket client (both api and event).
316+
* \tparam WsClientT WsClient or WssClient (WebSocket SSL)
317+
* \param client reference of the client instance
318+
*/
300319
template <typename WsClientT>
301320
static void set_ws_reverse_client_headers(WsClientT &client) {
302321
client.config.header.emplace("User-Agent", CQAPP_USER_AGENT);
@@ -305,15 +324,22 @@ static void set_ws_reverse_client_headers(WsClientT &client) {
305324
}
306325
}
307326

327+
/**
328+
* \brief Create a reverse websocket api client instance.
329+
* \tparam WsClientT WsClient or WssClient (WebSocket SSL)
330+
* \param server_port_path destination to connect
331+
* \return the newly created client instance (as shared_ptr)
332+
*/
308333
template <typename WsClientT>
309-
static shared_ptr<WsClientT> init_ws_reverse_api_client(const string &api_url) {
310-
auto client = make_shared<WsClientT>(api_url);
334+
static shared_ptr<WsClientT> init_ws_reverse_api_client(const string &server_port_path) {
335+
auto client = make_shared<WsClientT>(server_port_path);
311336
set_ws_reverse_client_headers<WsClientT>(*client);
312-
client->on_message = api_on_message<WsClientT>;
337+
client->on_message = ws_api_on_message<WsClientT>;
313338
return client;
314339
}
315340

316341
void ApiServer::init_ws_reverse() {
342+
// for api client, we create the instance at initialization stage
317343
try {
318344
if (boost::algorithm::starts_with(config.ws_reverse_api_url, "ws://")) {
319345
ws_reverse_api_client_.ws = init_ws_reverse_api_client<WsClient>(
@@ -325,9 +351,11 @@ void ApiServer::init_ws_reverse() {
325351
ws_reverse_api_client_is_wss_ = true;
326352
}
327353
} catch (...) {
354+
// in case "init_ws_reverse_api_client()" failed due to invalid "server_port_path"
328355
ws_reverse_api_client_is_wss_ = nullopt;
329356
}
330357

358+
// for event client, we just calculate the "server_port_path"
331359
if (boost::algorithm::starts_with(config.ws_reverse_event_url, "ws://")) {
332360
ws_reverse_event_server_port_path_ = config.ws_reverse_event_url.substr(strlen("ws://"));
333361
ws_reverse_event_client_is_wss_ = false;
@@ -394,7 +422,7 @@ void ApiServer::start() {
394422
+ ws_server_->config.address + ":" + to_string(ws_server_->config.port));
395423
}
396424

397-
if (config.use_ws_reverse /* use ws reverse */
425+
if (config.use_ws_reverse /* use reverse websocket */
398426
&& ws_reverse_api_client_is_wss_.has_value() /* successfully initialized */) {
399427
ws_reverse_api_client_started_ = true;
400428
ws_reverse_api_thread_ = thread([&]() {
@@ -448,19 +476,19 @@ template <typename WsClientT>
448476
static bool push_ws_reverse_event(const string &server_port_path, const json &payload) {
449477
auto succeeded = false;
450478
try {
451-
WsClientT client(server_port_path);
479+
WsClientT client(server_port_path); // this may fail due to invalid "server_port_path"
452480
set_ws_reverse_client_headers<WsClientT>(client);
453481
client.on_open = [&](shared_ptr<typename WsClientT::Connection> connection) {
454482
const auto send_stream = make_shared<typename WsClientT::SendStream>();
455483
*send_stream << payload.dump();
456484
connection->send(send_stream);
457-
connection->send_close(1000);
485+
connection->send_close(1000); // close connection after sending the event
458486
succeeded = true;
459487
};
460488
client.start();
461489
} catch (...) {
462-
// maybe "server_port_path" not valid,
463-
// maybe connection failed,
490+
// maybe "server_port_path" is not valid
491+
// maybe connection is failed
464492
// maybe the end of world came
465493
}
466494
return succeeded;
@@ -478,10 +506,10 @@ void ApiServer::push_event(const json &payload) const {
478506
count++;
479507
}
480508
}
481-
Log::d(TAG, u8"已成功向 " + to_string(count) + u8" 个客户端推送事件");
509+
Log::d(TAG, u8"已成功向 " + to_string(count) + u8" 个 WebSocket 客户端推送事件");
482510
}
483511

484-
if (config.use_ws_reverse /* use ws reverse */
512+
if (config.use_ws_reverse /* use reverse websocket */
485513
&& ws_reverse_event_client_is_wss_.has_value() /* successfully initialized */) {
486514
Log::d(TAG, u8"开始通过 WebSocket 反向客户端上报事件");
487515
bool succeeded;

src/api/server_class.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ class ApiServer {
5656

5757
bool initialized_ = false;
5858

59+
// http api server
5960
std::shared_ptr<SimpleWeb::Server<SimpleWeb::HTTP>> http_server_;
6061
std::thread http_thread_;
6162
bool http_server_started_ = false;
6263

64+
// websocket api and event server
6365
std::shared_ptr<SimpleWeb::SocketServer<SimpleWeb::WS>> ws_server_;
6466
std::thread ws_thread_;
6567
bool ws_server_started_ = false;
6668

69+
// reverse websocket api client
6770
union WsReverseApiClient {
6871
std::shared_ptr<SimpleWeb::SocketClient<SimpleWeb::WS>> ws;
6972
std::shared_ptr<SimpleWeb::SocketClient<SimpleWeb::WSS>> wss;
@@ -76,13 +79,33 @@ class ApiServer {
7679
std::thread ws_reverse_api_thread_;
7780
bool ws_reverse_api_client_started_ = false;
7881

82+
// reverse websocket event client
7983
std::string ws_reverse_event_server_port_path_;
8084
std::optional<bool> ws_reverse_event_client_is_wss_;
8185

86+
/**
87+
* This will be called in start().
88+
*/
8289
void init();
90+
91+
/**
92+
* Init http api server.
93+
*/
8394
void init_http();
95+
96+
/**
97+
* Init websocket server.
98+
*/
8499
void init_ws();
100+
101+
/**
102+
* Init reverse websocket client.
103+
*/
85104
void init_ws_reverse();
105+
106+
/**
107+
* This will be called in stop().
108+
*/
86109
void finalize();
87110
void finalize_http();
88111
void finalize_ws();

0 commit comments

Comments
 (0)