示例#1
0
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);
        }
    }
}
示例#2
0
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");
            }
        }
	}
}
示例#3
0
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;

}