22 #include <boost/filesystem.hpp> 25 #include <Wt/WHBoxLayout> 27 #include <Wt/WStackedWidget> 29 #include <Wt/WVBoxLayout> 31 #include "goby/common/time.h" 32 #include "goby/util/dynamic_protobuf_manager.h" 35 #include "liaison_wt_thread.h" 41 boost::shared_ptr<zmq::context_t> goby::common::Liaison::zmq_context_(
new zmq::context_t(1));
42 std::vector<void*> goby::common::Liaison::plugin_handles_;
46 int main(
int argc,
char* argv[])
48 glog.set_lock_action(goby::common::logger_lock::lock);
51 char* plugins = getenv(
"GOBY_LIAISON_PLUGINS");
54 std::string s_plugins(plugins);
55 std::vector<std::string> plugin_vec;
56 boost::split(plugin_vec, s_plugins, boost::is_any_of(
";:,"));
58 for (
int i = 0, n = plugin_vec.size(); i < n; ++i)
60 glog.is(VERBOSE) &&
glog <<
"Loading liaison plugin library: " << plugin_vec[i]
62 void* handle = dlopen(plugin_vec[i].c_str(), RTLD_LAZY);
64 goby::common::Liaison::plugin_handles_.push_back(handle);
66 glog.is(DIE) &&
glog <<
"Failed to open library: " << plugin_vec[i] << std::endl;
70 int return_value = goby::run<goby::common::Liaison>(argc, argv, &goby::common::liaison_cfg_);
71 goby::util::DynamicProtobufManager::protobuf_shutdown();
73 for (
int i = 0, n = goby::common::Liaison::plugin_handles_.size(); i < n; ++i)
74 dlclose(goby::common::Liaison::plugin_handles_[i]);
79 goby::common::Liaison::Liaison(protobuf::LiaisonConfig* cfg)
80 : ZeroMQApplicationBase(&zeromq_service_, cfg), zeromq_service_(zmq_context_),
81 pubsub_node_(&zeromq_service_, cfg->base().pubsub_config())
84 for (
int i = 0, n = cfg->load_shared_library_size(); i < n; ++i)
86 glog.is(VERBOSE) &&
glog <<
"Loading shared library: " << cfg->load_shared_library(i)
90 goby::util::DynamicProtobufManager::load_from_shared_lib(cfg->load_shared_library(i));
94 glog.is(DIE) &&
glog <<
"Failed ... check path provided or add to /etc/ld.so.conf " 95 <<
"or LD_LIBRARY_PATH" << std::endl;
100 goby::util::DynamicProtobufManager::enable_compilation();
101 for (
int i = 0, n = cfg->load_proto_file_size(); i < n; ++i)
102 load_proto_file(cfg->load_proto_file(i));
105 for (
int i = 0, n = cfg->load_proto_dir_size(); i < n; ++i)
107 boost::filesystem::path current_dir(cfg->load_proto_dir(i));
109 for (boost::filesystem::directory_iterator iter(current_dir), end; iter != end; ++iter)
111 #if BOOST_FILESYSTEM_VERSION == 3 112 if (iter->path().extension().string() ==
".proto")
114 if (iter->path().extension() ==
".proto")
117 load_proto_file(iter->path().string());
121 pubsub_node_.subscribe_all();
122 zeromq_service_.connect_inbox_slot(&Liaison::inbox,
this);
124 protobuf::ZeroMQServiceConfig ipc_sockets;
125 protobuf::ZeroMQServiceConfig::Socket* internal_publish_socket = ipc_sockets.add_socket();
126 internal_publish_socket->set_socket_type(protobuf::ZeroMQServiceConfig::Socket::PUBLISH);
127 internal_publish_socket->set_socket_id(LIAISON_INTERNAL_PUBLISH_SOCKET);
128 internal_publish_socket->set_transport(protobuf::ZeroMQServiceConfig::Socket::INPROC);
129 internal_publish_socket->set_connect_or_bind(protobuf::ZeroMQServiceConfig::Socket::BIND);
130 internal_publish_socket->set_socket_name(liaison_internal_publish_socket_name());
132 protobuf::ZeroMQServiceConfig::Socket* internal_subscribe_socket = ipc_sockets.add_socket();
133 internal_subscribe_socket->set_socket_type(protobuf::ZeroMQServiceConfig::Socket::SUBSCRIBE);
134 internal_subscribe_socket->set_socket_id(LIAISON_INTERNAL_SUBSCRIBE_SOCKET);
135 internal_subscribe_socket->set_transport(protobuf::ZeroMQServiceConfig::Socket::INPROC);
136 internal_subscribe_socket->set_connect_or_bind(protobuf::ZeroMQServiceConfig::Socket::BIND);
137 internal_subscribe_socket->set_socket_name(liaison_internal_subscribe_socket_name());
139 zeromq_service_.merge_cfg(ipc_sockets);
140 zeromq_service_.subscribe_all(LIAISON_INTERNAL_SUBSCRIBE_SOCKET);
144 std::string doc_root;
146 if (cfg->has_docroot())
147 doc_root = cfg->docroot();
148 else if (boost::filesystem::exists(boost::filesystem::path(GOBY_LIAISON_COMPILED_DOCROOT)))
149 doc_root = GOBY_LIAISON_COMPILED_DOCROOT;
150 else if (boost::filesystem::exists(boost::filesystem::path(GOBY_LIAISON_INSTALLED_DOCROOT)))
151 doc_root = GOBY_LIAISON_INSTALLED_DOCROOT;
153 throw(std::runtime_error(
"No valid docroot found for Goby Liaison. Set docroot to the " 154 "valid path to what is normally /usr/share/goby/liaison"));
157 std::vector<std::string> wt_argv_vec;
158 std::string str = cfg->base().app_name() +
" --docroot " + doc_root +
" --http-port " +
159 goby::util::as<std::string>(cfg->http_port()) +
" --http-address " +
160 cfg->http_address() +
" " + cfg->additional_wt_http_params();
161 boost::split(wt_argv_vec, str, boost::is_any_of(
" "));
163 char* wt_argv[wt_argv_vec.size()];
165 glog.is(DEBUG1) &&
glog <<
"setting Wt cfg to: " << std::flush;
166 for (
int i = 0, n = wt_argv_vec.size(); i < n; ++i)
168 wt_argv[i] =
new char[wt_argv_vec[i].size() + 1];
169 strcpy(wt_argv[i], wt_argv_vec[i].c_str());
170 glog.is(DEBUG1) &&
glog <<
"\t" << wt_argv[i] << std::endl;
173 wt_server_.setServerConfiguration(wt_argv_vec.size(), wt_argv);
176 for (
int i = 0, n = wt_argv_vec.size(); i < n; ++i)
delete[] wt_argv[i];
178 wt_server_.addEntryPoint(Wt::Application, goby::common::create_wt_application);
180 if (!wt_server_.start())
182 glog.is(DIE) &&
glog <<
"Could not start Wt HTTP server." << std::endl;
185 catch (Wt::WServer::Exception& e)
187 glog.is(DIE) &&
glog <<
"Could not start Wt HTTP server. Exception: " << e.what()
192 void goby::common::Liaison::load_proto_file(
const std::string& path)
194 #if BOOST_FILESYSTEM_VERSION == 3 195 boost::filesystem::path bpath = boost::filesystem::absolute(path);
197 boost::filesystem::path bpath = boost::filesystem::complete(path);
201 glog.is(VERBOSE) &&
glog <<
"Loading protobuf file: " << bpath << std::endl;
203 if (!goby::util::DynamicProtobufManager::user_descriptor_pool().FindFileByName(bpath.string()))
204 glog.is(DIE) &&
glog <<
"Failed to load file." << std::endl;
207 void goby::common::Liaison::loop()
218 void goby::common::Liaison::inbox(MarshallingScheme marshalling_scheme,
219 const std::string& identifier,
const std::string& data,
222 glog.is(DEBUG2) &&
glog <<
"Liaison: got message with identifier: " << identifier
223 <<
" from socket: " << socket_id << std::endl;
224 zeromq_service_.send(marshalling_scheme, identifier, data, LIAISON_INTERNAL_PUBLISH_SOCKET);
226 if (socket_id == LIAISON_INTERNAL_SUBSCRIBE_SOCKET)
228 glog.is(DEBUG2) &&
glog <<
"Sending to pubsub node: " << identifier << std::endl;
229 pubsub_node_.publish(marshalling_scheme, identifier, data);
common::FlexOstream glog
Access the Goby logger through this object.