#include "PingPong.h" #include #include 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( string config) : node(), counter( 0 ), pingId( 0 ), config_file(config) { Timer::setInterval( 5000 ); } // destruction PingPong::~PingPong() { } // implementation of the startup interface void PingPong::startup() { using boost::property_tree::ptree; using boost::property_tree::json_parser::read_json; // set up logging logging_rootlevel_debug(); logging_classlevel_debug(PingPong); logging_info( "[PINGPONG]\t starting up PingPong service ... " ); // read config ptree config; try { read_json(config_file, config); } catch ( exception& e ) { logging_warn("ERROR: Failed to read config file »" << config_file << "«: "); logging_warn(e.what()); logging_warn("---> Using fallback config."); config.put("ariba.spovnet_name", "pingpong"); } // use node name also in the application name = config.get("ariba.node_name", "NO_NAME"); // bind communication and node listener node.bind( this ); /*NodeListener*/ node.bind( this, PingPong::PINGPONG_SERVICEID); /*CommunicationListener*/ // connecting logging_debug( "connecting ... " ); node.connect(config.get_child("ariba")); // ping pong started up... logging_info( "[PINGPONG]\t pingpong starting up with" << " [spovnetid " << node.getSpoVNetId().toString() << "]" << " and [nodeid " << node.getNodeId().toString() << "]" ); } // implementation of the startup interface void PingPong::shutdown() { logging_info( "[PINGPONG]\t 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*/ // 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 // NOTE: Currently ariba only supports the Chord overlay. // 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 // NOTE: This example still uses the old deprecated ariba::message messages // with the ariba built-in serialization. // For future applications please use the new reboost::message_t messages. // Data is stored in high efficient zero-copy buffers of type // reboost::shared_buffer_t. These buffers hold plain data, so you have to // serialize the data "on your own". // We recommend third-party serialization libraries like: // - Protocol Buffers (http://en.wikipedia.org/wiki/Protocol_Buffers) // - MessagePack (http://en.wikipedia.org/wiki/MessagePack) // don't do anything if we have no neighbors if ( node.getNeighborNodes().size() == 0) { logging_info( "[PINGPONG]\t +++ no neighbors +++" ); return; } pingId++; logging_info( "\n|||||||||| >>>>>>>>>>\n" << "[PINGPONG]\t 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 ){ logging_info( "[PINGPONG]\t sending ping message to " << nid.toString() ); 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( "\n<<<<<<<<<< ||||||||||\n" << "[PINGPONG]\t RECEIVED ping message on link " << lnk.toString() << " " << (node.isLinkDirect(lnk) ? "[DIRECT-LINK]" : "[INDIRECT-LINK]") << " HopCount: " << node.getHopCount(lnk) << " from node " << remote.toString() << " (" << pingmsg->getName() << ")" << ": " << pingmsg->info() ); delete pingmsg; } 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) { 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