void ZmqEventSupplier::create_event_socket() { if (event_pub_sock == NULL) { // // Create the Publisher socket for real events and bind it // If the user has specified one IP address on the command line, // re-use it in the endpoint // event_pub_sock = new zmq::socket_t(zmq_context,ZMQ_PUB); int linger = 0; event_pub_sock->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); event_endpoint = "tcp://"; if (ip_specified == true) { event_endpoint = event_endpoint + user_ip + ':'; } else { event_endpoint = event_endpoint + "*:"; } // // Set a publisher HWM // Tango::Util *tg = Tango::Util::instance(); DServer *admin_dev = tg->get_dserver_device(); int hwm = tg->get_user_pub_hwm(); if (hwm == -1) hwm = admin_dev->zmq_pub_event_hwm; event_pub_sock->setsockopt(ZMQ_SNDHWM,&hwm,sizeof(hwm)); // // Bind the publisher socket to one ephemeral port // tango_bind(event_pub_sock,event_endpoint); // // If needed, replace * by host IP address in enpoint string // if (ip_specified == false) { event_endpoint.replace(6,1,host_ip); } } }
void ZmqEventSupplier::push_heartbeat_event() { time_t delta_time; time_t now_time; // // Heartbeat - check wether a heartbeat event has been sent recently // if not then send it. A heartbeat contains no data, it is used by the // consumer to know that the supplier is still alive. // Tango::Util *tg = Tango::Util::instance(); DServer *adm_dev = tg->get_dserver_device(); now_time = time(NULL); delta_time = now_time - adm_dev->last_heartbeat_zmq; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta time since last heartbeat " << delta_time << endl; if (heartbeat_name_init == false) { // // Build heartbeat name // This is something like // tango://host:port/dserver/exec_name/inst_name.heartbeat when using DB // tango://host:port/dserver/exec_name/inst_name#dbase=no.heartbeat when using file as database // heartbeat_event_name = heartbeat_event_name + adm_dev->get_full_name(); if (Util::_FileDb == true) heartbeat_event_name = heartbeat_event_name + MODIFIER_DBASE_NO; heartbeat_event_name = heartbeat_event_name + ".heartbeat"; heartbeat_name_init = true; } // // We here compare delta_time to 8 and not to 10. // This is necessary because, sometimes the polling thread is some // milli second in advance. The computation here is done in seconds // So, if the polling thread is in advance, delta_time computed in // seconds will be 9 even if in reality it is 9,9 // if (delta_time >= 8) { int nb_event = 1; cout3 << "ZmqEventSupplier::push_heartbeat_event(): detected heartbeat event for " << heartbeat_event_name << endl; cout3 << "ZmqEventSupplier::push_heartbeat_event(): delta _time " << delta_time << endl; if (double_send_heartbeat == true) { nb_event = 2; double_send_heartbeat = false; } while (nb_event != 0) { // // Create zmq message // zmq::message_t name_mess(heartbeat_event_name.size()); memcpy(name_mess.data(),(void *)heartbeat_event_name.data(),heartbeat_event_name.size()); bool endian_mess_sent = false; bool call_mess_sent = false; try { // // For debug and logging purposes // if (nb_event == 1) { if (omniORB::trace(20)) { omniORB::logger log; log << "ZMQ: Pushing some data" << '\n'; } if (omniORB::trace(30)) { { omniORB::logger log; log << "ZMQ: Event name" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)name_mess.data(),name_mess.size()); { omniORB::logger log; log << "ZMQ: Endianess" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)endian_mess.data(),endian_mess.size()); { omniORB::logger log; log << "ZMQ: Call info" << '\n'; } omni::giopStream::dumpbuf((unsigned char *)heartbeat_call_mess.data(),heartbeat_call_mess.size()); } } // // Push the event // adm_dev->last_heartbeat_zmq = now_time; heartbeat_pub_sock->send(name_mess,ZMQ_SNDMORE); heartbeat_pub_sock->send(endian_mess,ZMQ_SNDMORE); endian_mess_sent = true; heartbeat_pub_sock->send(heartbeat_call_mess,0); call_mess_sent = true; // // For reference counting on zmq messages which do not have a local scope // endian_mess.copy(&endian_mess_2); heartbeat_call_mess.copy(&heartbeat_call_mess_2); nb_event--; } catch(...) { cout3 << "ZmqEventSupplier::push_heartbeat_event() failed !\n"; if (endian_mess_sent == true) endian_mess.copy(&endian_mess_2); if (call_mess_sent == true) heartbeat_call_mess.copy(&heartbeat_call_mess_2); TangoSys_OMemStream o; o << "Can't push ZMQ heartbeat event for event "; o << heartbeat_event_name; if (zmq_errno() != 0) o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; else o << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::push_heartbeat_event"); } } } }
void ZmqEventSupplier::create_mcast_socket(string &mcast_data,int rate,McastSocketPub &ms) { // // Create the Publisher socket for real events and bind it // If the user has specified one IP address on the command line, // re-use it in the endpoint // ms.pub_socket = new zmq::socket_t(zmq_context,ZMQ_PUB); ms.endpoint = MCAST_PROT; if (ip_specified == true) { ms.endpoint = ms.endpoint + user_ip + ';'; } else { ApiUtil *au = ApiUtil::instance(); vector<string> adrs; au->get_ip_from_if(adrs); for (unsigned int i = 0;i < adrs.size();++i) { if (adrs[i].find("127.") == 0) continue; ms.endpoint = ms.endpoint + adrs[i] + ';'; break; } } ms.endpoint = ms.endpoint + mcast_data; int linger = 0; ms.pub_socket->setsockopt(ZMQ_LINGER,&linger,sizeof(linger)); // // Change multicast hops // Tango::Util *tg = Tango::Util::instance(); DServer *admin_dev = tg->get_dserver_device(); int nb_hops = admin_dev->mcast_hops; ms.pub_socket->setsockopt(ZMQ_MULTICAST_HOPS,&nb_hops,sizeof(nb_hops)); // // Change PGM rate to default value (80 Mbits/sec) or to user defined value // int local_rate = rate; ms.pub_socket->setsockopt(ZMQ_RATE,&local_rate,sizeof(local_rate)); // // Bind the publisher socket to the specified port // if (zmq_bind(*(ms.pub_socket),ms.endpoint.c_str()) != 0) { TangoSys_OMemStream o; o << "Can't bind ZMQ socket with endpoint "; o << ms.endpoint; o << "\nZmq error: " << zmq_strerror(zmq_errno()) << ends; Except::throw_exception((const char *)"DServer_Events", o.str(), (const char *)"ZmqEventSupplier::create_mcast_event_socket"); } // // The connection string returned to client does not need the host IP at all // ms.endpoint = MCAST_PROT + mcast_data; }