32using Json = nlohmann::json;
35std::map<std::string, std::pair<std::string, std::string>>
filter_info = {
36 {
"apollo.dreamview.Obstacles", {
"perception.PerceptionObstacles",
""}},
37 {
"apollo.dreamview.CameraUpdate", {
"drivers.Image",
""}},
38 {
"apollo.dreamview.PointCloud", {
"PointCloud",
"sensor"}}};
44 websocket_(websocket),
45 updater_manager_(updater_manager),
46 dv_plugin_manager_(dv_plugin_manager) {
47 RegisterDataHandlers();
48 RegisterMessageHandlers();
49 auto channel_manager =
50 apollo::cyber::service_discovery::TopologyManager::Instance()
52 auto topology_callback =
54 this->RefreshChannels(change_msg);
56 channel_manager->AddChangeListener(topology_callback);
59void SocketManager::RegisterDataHandlers() {
60 enabled_ = GetProtoFromFile(FLAGS_data_handler_config_path,
61 &data_handler_base_conf_);
63 AERROR <<
"Unable to parse data handler configuration from file "
64 << FLAGS_data_handler_config_path;
66 for (
auto &data_handler_iter :
67 dv_plugin_manager_->data_handler_conf_.data_handler_info()) {
69 data_handler_iter.first) !=
71 AERROR <<
"There are duplicate updater handlers between dv and plugins";
74 auto data_handler_info =
75 data_handler_base_conf_.mutable_data_handler_info();
76 (*data_handler_info)[data_handler_iter.first] = data_handler_iter.second;
78 AINFO <<
"data_handler_base_conf_: " << data_handler_base_conf_.DebugString();
89void SocketManager::RegisterMessageHandlers() {
97 response[
"action"] =
"response";
98 response[
"data"][
"info"] = {};
99 response[
"data"][
"info"][
"code"] = this->Subscribe(json) ? 0 : -1;
100 websocket_->
SendData(conn, response.dump());
107 response[
"action"] =
"response";
108 response[
"data"][
"info"] = {};
109 response[
"data"][
"info"][
"code"] = this->UnSubscribe(json) ? 0 : -1;
110 websocket_->
SendData(conn, response.dump());
114bool SocketManager::GetDataUpdaterChannels(
const std::string &updater_path,
115 std::vector<std::string> *channels) {
116 UpdaterBase *updater = updater_manager_->
GetUpdater(updater_path);
117 UpdaterWithChannelsBase *updater_with_channels =
118 dynamic_cast<UpdaterWithChannelsBase *
>(updater);
119 if (updater_with_channels ==
nullptr) {
122 updater_with_channels->GetChannelMsg(channels);
126bool SocketManager::ModifyUpdaterChannels(
const std::string &updater_path,
127 const std::string &channel_name,
128 const std::string &operation) {
129 UpdaterBase *updater = updater_manager_->
GetUpdater(updater_path);
130 UpdaterWithChannelsBase *updater_with_channels =
131 dynamic_cast<UpdaterWithChannelsBase *
>(updater);
132 if (updater_with_channels ==
nullptr) {
135 auto iter = std::find(updater_with_channels->channels_.begin(),
136 updater_with_channels->channels_.end(), channel_name);
137 if (operation ==
"join" && iter == updater_with_channels->channels_.end()) {
138 updater_with_channels->channels_.emplace_back(channel_name);
139 }
else if (operation ==
"leave" &&
140 iter != updater_with_channels->channels_.end()) {
141 updater_with_channels->channels_.erase(iter);
146bool SocketManager::Subscribe(
const Json &json) {
147 const std::string url = json[
"data"][
"info"][
"websocketName"];
148 double time_interval_ms = 0;
151 std::string channel_name;
156 Json subscribe_param = {};
157 std::vector<std::string> json_path = {
"data",
"info",
"param"};
159 return updater_manager_->
Start(url, time_interval_ms, channel_name,
163bool SocketManager::UnSubscribe(
const Json &json) {
164 const std::string url = json[
"data"][
"info"][
"websocketName"];
165 std::string channel_name;
170 return updater_manager_->
Stop(url, channel_name);
173Json SocketManager::ClearDataHandlerChannelMsgs() {
174 Json response_data({});
178 for (
auto iter = data_handler_conf_.mutable_data_handler_info()->begin();
179 iter != data_handler_conf_.mutable_data_handler_info()->end();
181 if (iter->second.different_for_channels()) {
182 const std::string &
data_type = (*iter).first;
183 (*data_handler_conf_.mutable_data_handler_info())[
data_type]
187 complete_channel_count_.clear();
188 data_handler_channel_count_.clear();
192 response_data[
"info"] = data;
193 response_data[
"info"][
"code"] = 0;
194 return response_data;
197Json SocketManager::GetDataHandlerInfo() {
198 Json response_data({});
200 data_handler_conf_.Clear();
201 data_handler_channel_count_.clear();
202 complete_channel_count_.clear();
206 data_handler_base_conf_.mutable_data_handler_info()->begin();
207 iter != data_handler_base_conf_.mutable_data_handler_info()->end();
209 const std::string &
data_type = (*iter).first;
210 DataHandlerInfo updater_info;
211 updater_info.CopyFrom(iter->second);
212 if (
data_type == FLAGS_cyber_channels_key) {
214 auto topology_manager =
215 apollo::cyber::service_discovery::TopologyManager::Instance();
216 auto channel_manager = topology_manager->channel_manager();
218 std::vector<apollo::cyber::proto::RoleAttributes> role_attributes;
219 channel_manager->GetWriters(&role_attributes);
221 for (
const auto &role : role_attributes) {
222 if (!complete_channel_count_[role.channel_name()]) {
223 std::string proto_path;
224 apollo::cyber::message::ProtobufFactory::Instance()->GetProtoPath(
225 role.message_type(), proto_path);
226 if (proto_path.empty()) {
227 AWARN <<
"Cannot find proto location for message type "
228 << role.message_type();
231 auto channel_item = updater_info.add_channels();
232 channel_item->set_proto_path(proto_path);
233 channel_item->set_channel_name(role.channel_name());
234 channel_item->set_msg_type(role.message_type());
236 complete_channel_count_[role.channel_name()]++;
240 const std::string &updater_path = (*iter).second.data_name();
241 std::string proto_path;
242 apollo::cyber::message::ProtobufFactory::Instance()->GetProtoPath(
244 if (proto_path.empty()) {
245 AWARN <<
"Cannot find proto location for message type " <<
data_type;
248 updater_info.set_proto_path(proto_path);
249 if (iter->second.different_for_channels()) {
250 std::vector<std::string> channels;
251 if (!GetDataUpdaterChannels(updater_path, &channels)) {
254 for (
auto iter = channels.begin(); iter != channels.end(); iter++) {
255 if (!data_handler_channel_count_[*iter]) {
256 auto channel_item = updater_info.add_channels();
257 channel_item->set_channel_name(*iter);
259 data_handler_channel_count_[*iter]++;
263 (*data_handler_conf_.mutable_data_handler_info())[
data_type] =
269 response_data[
"info"] = data;
270 response_data[
"info"][
"code"] = 0;
271 return response_data;
277 clear_channel_msg ? ClearDataHandlerChannelMsgs() : GetDataHandlerInfo();
278 response[
"action"] =
"metadata";
282bool SocketManager::UpdateUpdaterInfo(
286 auto channel_item = updater_info.add_channels();
287 channel_item->set_channel_name(role_attr.channel_name());
290 channel_item->set_msg_type(role_attr.message_type());
291 std::string proto_path;
292 apollo::cyber::message::ProtobufFactory::Instance()->GetProtoPath(
293 role_attr.message_type(), proto_path);
294 if (proto_path.empty()) {
295 AWARN <<
"Cannot find proto location for message type "
296 << role_attr.message_type();
299 channel_item->set_proto_path(proto_path);
304bool SocketManager::UpdateCyberChannels(
306 DataHandlerInfo &updater_info) {
312 if (!complete_channel_count_[channel_name]) {
313 if (!UpdateUpdaterInfo(change_msg, updater_info))
return false;
314 complete_channel_count_[channel_name]++;
317 complete_channel_count_[channel_name]++;
319 complete_channel_count_[channel_name]--;
320 if (complete_channel_count_[channel_name] == 0) {
321 if (!UpdateUpdaterInfo(change_msg, updater_info))
return false;
328void SocketManager::RefreshDataHandlerChannels(
330 DataHandlerConf &data_handler_conf_diff,
bool &flag) {
333 std::string channel_name = role_attr.channel_name();
337 std::vector<std::string> records;
338 std::vector<std::string> other_record_node_name;
339 auto *record_player_factory = RecordPlayerFactory::Instance();
340 record_player_factory->GetAllRecords(&records);
341 const std::string current_record = record_player_factory->GetCurrentRecord();
342 for (
auto iter = records.begin(); iter != records.end(); iter++) {
343 if (current_record.empty() || *iter != current_record) {
344 std::string other_node_name =
"record_player_factory_" + *iter;
345 other_record_node_name.push_back(other_node_name);
349 std::string node_name = role_attr.node_name();
350 for (
auto iter = data_handler_base_conf_.mutable_data_handler_info()->begin();
351 iter != data_handler_base_conf_.mutable_data_handler_info()->end();
353 const std::string &
data_type = (*iter).first;
354 DataHandlerInfo updater_info;
355 updater_info.set_data_name(iter->second.data_name());
356 updater_info.set_different_for_channels(
357 iter->second.different_for_channels());
359 if (
data_type == FLAGS_cyber_channels_key) {
361 flag = UpdateCyberChannels(change_msg, updater_info);
364 if (!iter->second.different_for_channels()) {
365 (*data_handler_conf_diff.mutable_data_handler_info())[
data_type] =
375 int index_channel = 0;
381 if (index != -1 && index_channel != -1 &&
382 (current_record.empty() ||
383 std::find(other_record_node_name.begin(),
384 other_record_node_name.end(),
385 node_name) == other_record_node_name.end())) {
388 if (!data_handler_channel_count_[channel_name]) {
390 auto channel_item = updater_info.add_channels();
391 channel_item->set_channel_name(channel_name);
392 if (!ModifyUpdaterChannels(iter->second.data_name(), channel_name,
396 data_handler_channel_count_[channel_name]++;
398 data_handler_channel_count_[channel_name]--;
399 if (data_handler_channel_count_[channel_name] == 0) {
401 auto channel_item = updater_info.add_channels();
402 channel_item->set_channel_name(channel_name);
403 if (!ModifyUpdaterChannels(iter->second.data_name(), channel_name,
410 (*data_handler_conf_diff.mutable_data_handler_info())[
data_type] =
415void SocketManager::RefreshChannels(
422 DataHandlerConf data_handler_conf_diff;
425 RefreshDataHandlerChannels(change_msg, data_handler_conf_diff, flag);
436 response[
"data"][
"info"] = data;
437 response[
"data"][
"info"][
"code"] = 0;
static bool GetStringByPath(const nlohmann::json &json, const std::string &path, std::string *value)
Get a string value from the given json and path.
static bool GetJsonByPath(const nlohmann::json &json, const std::vector< std::string > &paths, nlohmann::json *value)
Get the json from the given json and path.
static nlohmann::json ProtoToTypedJson(const std::string &json_type, const google::protobuf::Message &proto)
Convert proto to a json string.
static bool GetNumberByPath(const nlohmann::json &json, const std::string &path, T *value)
Get a number value from the given json and path.
A class that manages dreamview plus plug-ins.
void BrocastDataHandlerConf(bool clear_channel_msg=false)
Broadcast data handler conf for all connections
SocketManager(WebSocketHandler *websocket, UpdaterManager *updater_manager, DvPluginManager *dv_plugin_manager)
Constructor of SocketManager.
Management for all data updater.
bool Start(const std::string &path_name, const double &time_interval_ms, const std::string &channel_name="", nlohmann::json *subscribe_param=nullptr)
Start a updater implemetnent.
UpdaterBase * GetUpdater(const std::string &path_name)
Get registered updater
bool Stop(const std::string &path_name, const std::string &channel_name)
Stop updater publish data.
The WebSocketHandler, built on top of CivetWebSocketHandler, is a websocket handler that handles diff...
bool BroadcastData(const std::string &data, bool skippable=false)
Sends the provided data to all the connected clients.
void RegisterMessageHandler(std::string type, MessageHandler handler)
Add a new message handler for a message type.
bool SendData(Connection *conn, const std::string &data, bool skippable=false, int op_code=MG_WEBSOCKET_OPCODE_TEXT)
Sends the provided data to a specific connected client.
void RegisterConnectionReadyHandler(ConnectionReadyHandler handler)
Add a new handler for new connections.
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
std::map< std::string, std::pair< std::string, std::string > > filter_info
SocketManager to manage all websocket
optional RoleAttributes role_attr
optional OperateType operate_type
optional RoleType role_type
optional string channel_name
optional string message_type
map< string, DataHandlerInfo > data_handler_info