#include "PingPong.h" #include "ariba/utility/configuration/Configuration.h" using ariba::utility::Configuration; using namespace ariba; namespace ariba { namespace application { namespace pingpong { // logging use_logging_cpp( PingPong ); // the service that the pingpong wants to use ServiceID PingPong::PINGPONG_SERVICEID = ServiceID( 111 ); // construction PingPong::PingPong() : pingId( 0 ) { Timer::setInterval( 1000 ); } // destruction PingPong::~PingPong() { } // implementation of the startup interface void PingPong::startup() { logging_info( "starting up PingPong service ... " ); // create ariba module logging_debug( "creating ariba underlay module ... " ); ariba = new AribaModule(); // get the configuration object Configuration& config = Configuration::instance(); // generate spovnet name Name spovnetName("pingpong"); // get initiator flag this->isInitiator = Configuration::instance().read("node.initiator"); this->name = string(""); // get node name Name nodeName = Name::UNSPECIFIED; if (config.exists("node.name")) nodeName = config.read ("node.name"); // configure ariba module if (config.exists("ariba.ip.addr")) ariba->setProperty("ip.addr", config.read("ariba.ip.addr")); if (config.exists("ariba.tcp.port")) ariba->setProperty("tcp.port", config.read("ariba.tcp.port")); if (config.exists("ariba.udp.port")) ariba->setProperty("udp.port", config.read("ariba.udp.port")); if (config.exists("ariba.bootstrap.hints")) ariba->setProperty("bootstrap.hints", config.read("ariba.bootstrap.hints")); if (config.exists("pingpong.name")) name = config.read("pingpong.name"); // start ariba module ariba->start(); // create node and join node = new Node( *ariba, nodeName ); // bind communication and node listener node->bind( this ); /*NodeListener*/ node->bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/ // start node module node->start(); // when initiating, you can define the overlay type, default is Chord [CHORD_OVERLAY] SpoVNetProperties params; //params.setBaseOverlayType( SpoVNetProperties::ONE_HOP_OVERLAY ); // alternative: OneHop // initiate or join the spovnet if (!isInitiator) node->join(spovnetName); else node->initiate(spovnetName, params); // ping pong started up... logging_info( "pingpong starting up with" << " [spovnetid " << node->getSpoVNetId().toString() << "]" << " and [nodeid " << node->getNodeId().toString() << "]" ); } // implementation of the startup interface void PingPong::shutdown() { logging_info( "pingpong service starting shutdown sequence ..." ); // stop timer Timer::stop(); // leave spovnet node->leave(); // unbind communication and node listener node->unbind( this ); /*NodeListener*/ node->unbind( this, PingPong::PINGPONG_SERVICEID ); /*CommunicationListener*/ // stop the ariba module ariba->stop(); // delete node and ariba module delete node; delete ariba; // now we are completely shut down logging_info( "pingpong service shut down" ); } // timer event void PingPong::eventFunction() { // we ping all nodes that are known in the overlay structure // this can be all nodes (OneHop) overlay or just some neighbors // in case of a Chord or Kademlia structure // in this sample we use auto-links: we just send out our message // to the node and the link is established automatically. for more // control we would use the node->establishLink function to create // a link and start using the link in the CommunicationListener::onLinkUp // function that is implemented further down in PingPong::onLinkUp // logging_info( "pinging overlay neighbors with ping id " << ++pingId ); PingPongMessage pingmsg( pingId, name ); //----------------------------------------------------------------------- // Option 1: get all neighboring nodes and send the message to each //----------------------------------------------------------------------- counter++; if (counter<0 || counter>4) { counter = 0; string s; for (int i=0; i I am " << name << " and I know " << s); names.clear(); } vector nodes = node->getNeighborNodes(); BOOST_FOREACH( NodeID nid, nodes ){ node->sendMessage( pingmsg, nid, PingPong::PINGPONG_SERVICEID ); } //----------------------------------------------------------------------- // Option 2: send a "broadcast message" that actually does the same thing // internally, gets all neighboring nodes and sends the message //----------------------------------------------------------------------- // node->sendBroadcastMessage( pingmsg, PingPong::PINGPONG_SERVICEID ); } void PingPong::onJoinCompleted( const SpoVNetID& vid ) { logging_info( "pingpong node join completed, spovnetid=" << vid.toString() ); // start the timer to ping every second Timer::start(); } void PingPong::onJoinFailed( const SpoVNetID& vid ) { logging_error("pingpong node join failed, spovnetid=" << vid.toString() ); } void PingPong::onLeaveCompleted( const SpoVNetID& vid ){ logging_info("pingpong node leave completed, spovnetid=" << vid.toString() ); } void PingPong::onLeaveFailed( const SpoVNetID& vid ){ logging_error("pingpong node leave failed, spovnetid=" << vid.toString() ); } void PingPong::onMessage(const DataMessage& msg, const NodeID& remote, const LinkID& lnk) { PingPongMessage* pingmsg = msg.getMessage()->convert (); bool found=false; for (int i=0;igetName()) found=true; if (!found) names.push_back(pingmsg->getName()); // logging_info( "received ping message on link " << lnk.toString() // << " from node " << remote.toString() // << ": " << pingmsg->info() ); } void PingPong::onLinkUp(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-up event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkDown(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-down event for link " << lnk.toString() << " and node " << remote.toString() ); } void PingPong::onLinkChanged(const LinkID& lnk, const NodeID& remote){ logging_info( "link-changed event for link " << lnk.toString() << " and node " << remote.toString() ); } bool PingPong::onLinkRequest(const NodeID& remote, const DataMessage& msg) { logging_info( "node " << remote.toString() << " wants to build up a link with us ... allowing" ); return true; } void PingPong::onLinkFail(const LinkID& lnk, const NodeID& remote){ logging_info( "received link-failed event for link " << lnk.toString() << " and node " << remote.toString() ); } }}} // namespace ariba, application, pingpong