#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 use_status = false; Mode_S_Output_Type mode_s_output_type = Mode_S_Output_Type::DF_11_17_18; std::atomic use_mode_ac = false; std::atomic sbs_only_pos = false; std::atomic 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 ucoro::awaitable handle_in_loop_coro() { handle_in_loop(); co_return; } virtual ucoro::awaitable send_coro(const std::string&) { co_return; } 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(handle_in_loop_coro()); } ucoro::awaitable handle_in_loop_coro() override { co_await svr.flush_clients_coro(); co_await svr.tick_coro(); co_return; } ucoro::awaitable send_coro(const std::string& data) override { co_await svr.write_to_all_clients_coro(data); co_return; } 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(handle_in_loop_coro()); } ucoro::awaitable handle_in_loop_coro() override { co_await cli.tick_coro(); co_return; } ucoro::awaitable send_coro(const std::string& data) override { co_await cli.send_coro(data); co_return; } 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; ucoro::awaitable handle_in_loop_coro() override; ucoro::awaitable send_coro(const std::string& data) 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(handle_in_loop_coro()); } ucoro::awaitable handle_in_loop_coro() override { co_await cli.tick_coro(); co_return; } ucoro::awaitable send_coro(const std::string& data) override { co_await cli.send_coro(data); co_return; } 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 create_data_feed_from_type(const std::string& t) { std::shared_ptr ret{}; if (t == "Data_Feed_TCP_Server") ret = std::make_shared(); else if (t == "Data_Feed_UDP_Server") ret = std::make_shared(); else if (t == "Data_Feed_TCP_Client") ret = std::make_shared(); else if (t == "Data_Feed_UDP_Client") ret = std::make_shared(); 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> map; std::atomic empty_wait_milliseconds{}; std::atomic 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 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 convert_to_send_format(Data_Source* ds, const std::shared_ptr& feed, const std::shared_ptr& msg);