357 lines
10 KiB
C++
357 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "global.h"
|
|
|
|
enum class Output_Data_Format {
|
|
AVR,
|
|
AVR_MLAT,
|
|
BIN,
|
|
SBS,
|
|
BIN_ID
|
|
};
|
|
|
|
enum class Mode_S_Output_Type {
|
|
DF_11_17_18,
|
|
NO_POS_Mode_S,
|
|
ALL_Mode_S
|
|
};
|
|
|
|
struct Output_Format {
|
|
Output_Data_Format type = Output_Data_Format::BIN;
|
|
std::atomic<bool> use_status = false;
|
|
Mode_S_Output_Type mode_s_output_type = Mode_S_Output_Type::DF_11_17_18;
|
|
std::atomic<bool> use_mode_ac = false;
|
|
std::atomic<bool> sbs_only_pos = false;
|
|
std::atomic<bool> use_crc = false;
|
|
|
|
[[nodiscard]] Psc::JSON to_Json() const {
|
|
Psc::JSON ret = Psc::JSON::object();
|
|
Ret_J(type)
|
|
Ret_J(use_status)
|
|
Ret_J(mode_s_output_type)
|
|
Ret_J(use_mode_ac)
|
|
Ret_J(sbs_only_pos)
|
|
return ret;
|
|
}
|
|
|
|
void from_json(const Psc::JSON *that_json) {
|
|
Get_J(type)
|
|
Get_J(use_status)
|
|
Get_J(mode_s_output_type)
|
|
Get_J(use_mode_ac)
|
|
Get_J(sbs_only_pos)
|
|
}
|
|
};
|
|
|
|
|
|
class Data_Feed {
|
|
public:
|
|
virtual ~Data_Feed() = default;
|
|
BIN_Msg_Buffer msg_buffer{};
|
|
std::string key;
|
|
bool enable = false;
|
|
std::string type;
|
|
Output_Format output_format;
|
|
Frequency_Limit_Multi sbs_flm{};
|
|
virtual void handle_in_loop() {
|
|
|
|
}
|
|
virtual Psc::JSON to_json() {
|
|
Psc::JSON ret = Psc::JSON::object();
|
|
Ret_J(key);
|
|
Ret_J(enable);
|
|
Ret_J(type);
|
|
ret.append({"output_format", output_format.to_Json()});
|
|
return ret;
|
|
}
|
|
virtual void from_json(const Psc::JSON *that_json) {
|
|
Get_J(key)
|
|
Get_J(enable)
|
|
Get_J(type)
|
|
output_format.from_json(that_json->get("output_format"));
|
|
}
|
|
virtual Psc::JSON get_custom_state_json() {
|
|
return Psc::JSON::object();
|
|
}
|
|
virtual Psc::JSON get_state_json() {
|
|
Psc::JSON ret = msg_buffer.state_json();
|
|
ret.append_list(get_custom_state_json().children);
|
|
return ret;
|
|
}
|
|
bool check_and_open() {
|
|
if (_open_) return true;
|
|
bool ret = _open();
|
|
_open_ = true;
|
|
return ret;
|
|
}
|
|
|
|
void close() {
|
|
_open_ = false;
|
|
_close();
|
|
}
|
|
|
|
std::string to_string() {
|
|
return "Data_Feed【" + VAR_STR_3(key, enable, type) + "】";
|
|
}
|
|
protected:
|
|
Data_Feed() = default;
|
|
bool _open_ = false;
|
|
virtual bool _open() {
|
|
return true;
|
|
}
|
|
|
|
virtual void _close() {
|
|
|
|
}
|
|
};
|
|
|
|
|
|
class Data_Feed_TCP_Server : public Data_Feed {
|
|
public:
|
|
std::uint16_t port{};
|
|
size_t connect_user_buffer_size{};
|
|
size_t connect_system_buffer_size{};
|
|
Psc::asio_socket::TCP_Server_Coro svr;
|
|
Psc::JSON get_custom_state_json() override {
|
|
auto& state = svr.state;
|
|
Psc::JSON ret = Psc::JSON::object();
|
|
Ret_J(connect_system_buffer_size)
|
|
Ret_J(connect_user_buffer_size)
|
|
ret.key = "fixed";
|
|
auto t = VAR_JSON_1(state);
|
|
t.append(ret);
|
|
return t;
|
|
}
|
|
|
|
~Data_Feed_TCP_Server() override {}
|
|
void handle_in_loop() override {
|
|
//std::cout << socket.to_string() << "flush_clients" << std::endl;
|
|
ucoro::sync_await(svr.flush_clients_coro());
|
|
ucoro::sync_await(svr.tick_coro());
|
|
}
|
|
void from_json(const Psc::JSON* that_json) override {
|
|
Data_Feed::from_json(that_json);
|
|
Get_J(port);
|
|
Get_J(connect_user_buffer_size)
|
|
Get_J(connect_system_buffer_size)
|
|
}
|
|
Psc::JSON to_json() override {
|
|
Psc::JSON ret = Data_Feed::to_json();
|
|
Ret_J(port);
|
|
Ret_J(connect_user_buffer_size)
|
|
Ret_J(connect_system_buffer_size)
|
|
return ret;
|
|
}
|
|
void _close() override { svr.close(); }
|
|
bool _open() override {
|
|
svr.set_connect_user_buffer_size(connect_user_buffer_size);
|
|
svr.set_connect_system_buffer_size(connect_system_buffer_size);
|
|
svr.set_tcp_no_delay(false);
|
|
svr.create();
|
|
return ucoro::sync_await(svr.listen_coro("0.0.0.0", port));
|
|
}
|
|
Psc::JSON get_clients_json() {
|
|
Psc::JSON ret = Psc::JSON::array();
|
|
for (const auto& conn : svr.get_all_clients()) {
|
|
auto& info = conn->info;
|
|
Psc::JSON cur = Psc::JSON::object();
|
|
auto& fd = info.fd;
|
|
auto& cur_ip = info.sockaddr.ip;
|
|
auto& cur_port = info.sockaddr.port;
|
|
cur.append({"base", VAR_STR_3(cur_ip, cur_port, fd)});
|
|
cur.append({"state", conn->send_buffer.state_str()});
|
|
{
|
|
auto& ins = conn->push_speed.instant_speed;
|
|
auto& avr = conn->push_speed.average_speed;
|
|
cur.append({"send_speed(KB/s)", VAR_STR_2(ins, avr)});
|
|
}
|
|
{
|
|
auto& ins = conn->lose_speed.instant_speed;
|
|
auto& avr = conn->lose_speed.average_speed;
|
|
cur.append({"lose_speed(KB/s)", VAR_STR_2(ins, avr)});
|
|
}
|
|
{
|
|
auto& ins = conn->send_num.instant;
|
|
auto& avr =conn->send_num.average;
|
|
cur.append({"send_num(byte/次)", VAR_STR_2(ins, avr)});
|
|
}
|
|
ret.append(cur);
|
|
}
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
|
|
class Data_Feed_TCP_Client : public Data_Feed {
|
|
public:
|
|
void handle_in_loop() override {
|
|
ucoro::sync_await(cli.tick_coro());
|
|
}
|
|
std::string url;
|
|
Psc::JSON get_custom_state_json() override {
|
|
auto& state = cli.state;
|
|
return VAR_JSON_1(state);
|
|
}
|
|
std::uint16_t port{};
|
|
Psc::asio_socket::TCP_Client_Coro cli;
|
|
~Data_Feed_TCP_Client() override = default;
|
|
void _close() override { cli.close(); }
|
|
bool _open() override {
|
|
Psc::asio_socket::Sockaddr_In sockaddr_in;
|
|
sockaddr_in.ip = url;
|
|
sockaddr_in.port = port;
|
|
cli.set_dest_address(sockaddr_in);
|
|
cli.create();
|
|
ucoro::sync_await(cli.connect_coro());
|
|
return true;
|
|
}
|
|
void from_json(const Psc::JSON* that_json) override {
|
|
Data_Feed::from_json(that_json);
|
|
Get_J(url)
|
|
Get_J(port);
|
|
}
|
|
Psc::JSON to_json() override {
|
|
Psc::JSON ret = Data_Feed::to_json();
|
|
Ret_J(url);
|
|
Ret_J(port);
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
class Data_Feed_UDP_Server : public Data_Feed {
|
|
public:
|
|
Psc::JSON get_custom_state_json() override {
|
|
auto& state = svr.state;
|
|
return VAR_JSON_1(state);
|
|
}
|
|
|
|
|
|
|
|
Data_Feed_UDP_Server()= default;
|
|
~Data_Feed_UDP_Server() override = default;
|
|
void handle_in_loop() override;
|
|
[[nodiscard]] Psc::JSON get_clients_json() const {
|
|
Psc::JSON ret = Psc::JSON::array();
|
|
for (const auto& i : svr.clients) {
|
|
Psc::JSON cur = Psc::JSON::object();
|
|
cur.append({"ip", i.ip});
|
|
cur.append({"port", i.port});
|
|
ret.append(cur);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void from_json(const Psc::JSON* that_json) override {
|
|
Data_Feed::from_json(that_json);
|
|
Get_J(port);
|
|
}
|
|
Psc::JSON to_json() override {
|
|
Psc::JSON ret = Data_Feed::to_json();
|
|
Ret_J(port);
|
|
return ret;
|
|
}
|
|
void _close() override { svr.close(); }
|
|
bool _open() override;
|
|
std::uint16_t port{};
|
|
Psc::asio_socket::UDP_Server_Coro svr;
|
|
};
|
|
|
|
|
|
class Data_Feed_UDP_Client : public Data_Feed {
|
|
public:
|
|
Data_Feed_UDP_Client() {}
|
|
~Data_Feed_UDP_Client() override {}
|
|
Psc::JSON get_custom_state_json() override {
|
|
auto& state = cli.state;
|
|
return VAR_JSON_1(state);
|
|
}
|
|
void handle_in_loop() override {
|
|
ucoro::sync_await(cli.tick_coro());
|
|
}
|
|
Psc::asio_socket::UDP_Client_Coro cli;
|
|
std::string url;
|
|
std::uint16_t port{};
|
|
void from_json(const Psc::JSON* that_json) override {
|
|
Data_Feed::from_json(that_json);
|
|
Get_J(url)
|
|
Get_J(port);
|
|
}
|
|
Psc::JSON to_json() override {
|
|
Psc::JSON ret = Data_Feed::to_json();
|
|
Ret_J(url);
|
|
Ret_J(port);
|
|
return ret;
|
|
}
|
|
void _close() override {
|
|
std::cout << "udp客户端 目标地址:" << cli.dest_address.to_string() << "关闭!" << std::endl;
|
|
cli.close();
|
|
}
|
|
bool _open() override {
|
|
cli.create();
|
|
cli.set_dest_address(url, port);
|
|
ucoro::sync_await(cli.connect_coro());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
inline std::shared_ptr<Data_Feed> create_data_feed_from_type(const std::string& t) {
|
|
std::shared_ptr<Data_Feed> ret{};
|
|
if (t == "Data_Feed_TCP_Server") ret = std::make_shared<Data_Feed_TCP_Server>(); else
|
|
if (t == "Data_Feed_UDP_Server") ret = std::make_shared<Data_Feed_UDP_Server>(); else
|
|
if (t == "Data_Feed_TCP_Client") ret = std::make_shared<Data_Feed_TCP_Client>(); else
|
|
if (t == "Data_Feed_UDP_Client") ret = std::make_shared<Data_Feed_UDP_Client>(); else {
|
|
std::cout << "未知的 Data_Feed type类型! t:[" << t << "]"<< std::endl;
|
|
throw std::invalid_argument("unknown Data_Feed type: " + t);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
struct Data_feed_Config {
|
|
Psc::String_Pool pool_ = Psc::String_Pool(1600, 8* 1024); // 8192 * 1600 12.5 MB
|
|
Ordered_Map<std::string, std::shared_ptr<Data_Feed>> map;
|
|
std::atomic<std::uint16_t> empty_wait_milliseconds{};
|
|
std::atomic<std::uint16_t> packet_byte_size{};
|
|
size_t tcp_server_default_connect_user_buffer_size{};
|
|
size_t tcp_server_default_connect_system_buffer_size{};
|
|
Data_feed_Config() = default;
|
|
void init(const Psc::JSON* that_json) {
|
|
auto connect = that_json->get("list");
|
|
for (auto& it : connect->children) {
|
|
auto type = it.get_string("type");
|
|
std::shared_ptr<Data_Feed> t = create_data_feed_from_type(type);
|
|
t->from_json(&it);
|
|
map.push_back(t);
|
|
}
|
|
Get_J(empty_wait_milliseconds)
|
|
Get_J(tcp_server_default_connect_user_buffer_size)
|
|
Get_J(tcp_server_default_connect_system_buffer_size)
|
|
}
|
|
|
|
Psc::JSON list() {
|
|
auto connect_json = Psc::JSON::array();
|
|
for (auto& it : map.list()) {
|
|
connect_json.children.emplace_back(it->to_json());
|
|
}
|
|
return connect_json;
|
|
}
|
|
|
|
Psc::JSON to_json() {
|
|
Psc::JSON ret = Psc::JSON::object();
|
|
Ret_J(empty_wait_milliseconds)
|
|
Ret_J(packet_byte_size)
|
|
Ret_J(tcp_server_default_connect_user_buffer_size)
|
|
Ret_J(tcp_server_default_connect_system_buffer_size)
|
|
ret.append({"list", list()});
|
|
return ret;
|
|
}
|
|
Psc::JSON get_feed(const std::string& key);
|
|
void server(Global* g);
|
|
};
|
|
class Data_Source;
|
|
std::optional<std::string> convert_to_send_format(Data_Source* ds, const std::shared_ptr<Data_Feed>& feed, const std::shared_ptr<SSR::Msg>& msg);
|
|
|