Servus  1.2.0
A small set of network oriented utilities in C++ including a zeroconf implementation.
servus::Servus Class Reference

Simple wrapper for ZeroConf key/value pairs. More...

#include <servus.h>

+ Collaboration diagram for servus::Servus:

Classes

class  Result
 The ZeroConf operation result code. More...
 

Public Types

enum  Interface { IF_ALL = 0, IF_LOCAL = (unsigned)(-1) }
 
typedef std::map< std::string, std::map< std::string, std::string > > Data
 

Public Member Functions

SERVUS_API Servus (const std::string &name)
 Create a new service handle. More...
 
virtual SERVUS_API ~Servus ()
 Destruct this service. More...
 
SERVUS_API const std::string & getName () const
 
SERVUS_API void set (const std::string &key, const std::string &value)
 Set a key/value pair to be announced. More...
 
SERVUS_API Strings getKeys () const
 
SERVUS_API const std::string & get (const std::string &key) const
 
SERVUS_API Result announce (const unsigned short port, const std::string &instance)
 Start announcing the registered key/value pairs. More...
 
SERVUS_API void withdraw ()
 Stop announcing the registered key/value pairs. More...
 
SERVUS_API bool isAnnounced () const
 
SERVUS_API Strings discover (const Interface addr, const unsigned browseTime)
 Discover all announced key/value pairs. More...
 
SERVUS_API Result beginBrowsing (const servus::Servus::Interface addr)
 Begin the discovery of announced key/value pairs. More...
 
SERVUS_API Result browse (int32_t timeout=-1)
 Browse and process discovered key/value pairs. More...
 
SERVUS_API void endBrowsing ()
 Stop a discovery process and return all results. More...
 
SERVUS_API bool isBrowsing () const
 
SERVUS_API Strings getInstances () const
 
SERVUS_API Strings getKeys (const std::string &instance) const
 
SERVUS_API bool containsKey (const std::string &instance, const std::string &key) const
 
SERVUS_API const std::string & get (const std::string &instance, const std::string &key) const
 
SERVUS_API void addListener (Listener *listener)
 Add a listener which is invoked according to its supported callbacks. More...
 
SERVUS_API void removeListener (Listener *listener)
 Remove a listener to stop invokation on its supported callbacks. More...
 
SERVUS_API void getData (Data &data)
 

Static Public Member Functions

static SERVUS_API bool isAvailable ()
 

Friends

SERVUS_API std::ostream & operator<< (std::ostream &, const Servus &)
 Output the servus instance in human-readable format. More...
 

Detailed Description

Simple wrapper for ZeroConf key/value pairs.

The servus class allows simple announcement and discovery of key/value pairs using ZeroConf networking. The same instance can be used to announce and/or to browse a ZeroConf service. If the Servus library is compiled without zeroconf support (

See also
isAvailable()), this class does not do anything useful.

Example:

/* Copyright (c) 2012-2015, Stefan.Eilemann@epfl.ch
*
* This file is part of Servus <https://github.com/HBPVIS/Servus>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define BOOST_TEST_MODULE servus_servus
#include <boost/test/unit_test.hpp>
#include <servus/servus.h>
#include <random>
#include <thread>
#ifdef SERVUS_USE_DNSSD
# include <dns_sd.h>
#endif
uint16_t getRandomPort()
{
static std::random_device device;
static std::minstd_rand engine( device( ));
std::uniform_int_distribution< uint16_t > generator( 1024, 65535u );
return generator( engine );
}
BOOST_AUTO_TEST_CASE(test_servus)
{
const uint32_t port = getRandomPort();
std::string serviceName = "_servustest_" + std::to_string( port ) + "._tcp";
try
{
servus::Servus service( serviceName );
}
catch( const std::runtime_error& e )
{
if( getenv( "TRAVIS" ))
{
std::cerr << "Bailing, no avahi on a Travis CI setup" << std::endl;
BOOST_CHECK_EQUAL(
e.what(), "Can't setup avahi client: Daemon not running" );
return;
}
throw;
}
servus::Servus service( serviceName );
const servus::Servus::Result& result = service.announce( port,
std::to_string( port ));
BOOST_CHECK_EQUAL( service.getName(), serviceName );
{
// BOOST_CHECK_EQUAL gives a link error for Result::NOT_SUPPORTED
BOOST_CHECK( result == servus::Servus::Result::NOT_SUPPORTED );
return;
}
#ifdef SERVUS_USE_DNSSD
BOOST_CHECK( servus::Result::SUCCESS == kDNSServiceErr_NoError );
#endif
if( result != servus::Result::SUCCESS ) // happens on CI VMs
{
std::cerr << "Bailing, got " << result
<< ": looks like a broken zeroconf setup" << std::endl;
return;
}
BOOST_CHECK_EQUAL( result, result );
service.withdraw();
service.set( "foo", "bar" );
BOOST_CHECK( service.announce( port, std::to_string( port )));
servus::Strings hosts = service.discover( servus::Servus::IF_LOCAL, 2000 );
if( hosts.empty() && getenv( "TRAVIS" ))
{
std::cerr << "Bailing, got no hosts on a Travis CI setup" << std::endl;
return;
}
BOOST_REQUIRE_EQUAL( hosts.size(), 1 );
BOOST_CHECK_EQUAL( hosts.front(), std::to_string( port ));
BOOST_CHECK_EQUAL( service.get( hosts.front(), "foo" ), "bar" );
std::this_thread::sleep_for( std::chrono::milliseconds( 200 ));
service.set( "foobar", "42" );
std::this_thread::sleep_for( std::chrono::milliseconds( 2000 ));
hosts = service.discover( servus::Servus::IF_LOCAL, 2000 );
BOOST_REQUIRE_EQUAL( hosts.size(), 1 );
BOOST_CHECK_EQUAL( service.get( hosts.front(), "foobar" ), "42" );
BOOST_CHECK_EQUAL( service.getKeys().size(), 2 );
// continuous browse API
BOOST_CHECK( !service.isBrowsing( ));
BOOST_CHECK( service.beginBrowsing( servus::Servus::IF_LOCAL ));
BOOST_CHECK( service.isBrowsing( ));
// BOOST_CHECK_EQUAL gives a link error for Result::PENDING
BOOST_CHECK( service.beginBrowsing( servus::Servus::IF_LOCAL ) ==
BOOST_CHECK( service.isBrowsing( ));
BOOST_CHECK_EQUAL( service.browse( 200 ), service.browse( 0 ));
hosts = service.getInstances();
BOOST_REQUIRE_EQUAL( hosts.size(), 1 );
BOOST_CHECK_EQUAL( service.get( hosts.front(), "foo" ), "bar" );
BOOST_CHECK_EQUAL( service.getKeys().size(), 2 );
{ // test updates during browsing
servus::Servus service2( serviceName );
BOOST_CHECK( service2.announce( port+1, std::to_string( port+1 )));
BOOST_CHECK( service.browse( 2000 ));
hosts = service.getInstances();
BOOST_CHECK_EQUAL( hosts.size(), 2 );
}
std::this_thread::sleep_for( std::chrono::milliseconds( 500 ));
BOOST_CHECK( service.browse( 2000 ));
hosts = service.getInstances();
BOOST_CHECK_EQUAL( hosts.size(), 1 );
BOOST_CHECK( service.isBrowsing( ));
service.endBrowsing();
BOOST_CHECK( !service.isBrowsing( ));
hosts = service.getInstances();
BOOST_REQUIRE_EQUAL( hosts.size(), 1 );
BOOST_CHECK_EQUAL( service.get( hosts.front(), "foo" ), "bar" );
BOOST_CHECK_EQUAL( service.getKeys().size(), 2 );
}

Definition at line 43 of file servus.h.

Member Enumeration Documentation

Enumerator
IF_ALL 

use all interfaces

IF_LOCAL 

only local interfaces

Definition at line 46 of file servus.h.

Constructor & Destructor Documentation

SERVUS_API servus::Servus::Servus ( const std::string &  name)
explicit

Create a new service handle.

Parameters
namethe service descriptor, e.g., "_hwsd._tcp"
Version
1.1
virtual SERVUS_API servus::Servus::~Servus ( )
virtual

Destruct this service.

Version
1.1

Member Function Documentation

SERVUS_API void servus::Servus::addListener ( Listener listener)

Add a listener which is invoked according to its supported callbacks.

Parameters
listenerthe listener to be added, must not be nullptr
Version
1.2
SERVUS_API Result servus::Servus::announce ( const unsigned short  port,
const std::string &  instance 
)

Start announcing the registered key/value pairs.

Parameters
portthe service IP port in host byte order.
instancea host-unique instance name, hostname is used if empty.
Returns
the success status of the operation.
Version
1.1
SERVUS_API Result servus::Servus::beginBrowsing ( const servus::Servus::Interface  addr)

Begin the discovery of announced key/value pairs.

Parameters
addrthe scope of the discovery
Returns
the success status of the operation.
Version
1.1
SERVUS_API Result servus::Servus::browse ( int32_t  timeout = -1)

Browse and process discovered key/value pairs.

Parameters
timeoutThe time to spend browsing.
Returns
the success status of the operation.
Version
1.1
SERVUS_API bool servus::Servus::containsKey ( const std::string &  instance,
const std::string &  key 
) const
Returns
true if the given key was discovered.
Version
1.1
SERVUS_API Strings servus::Servus::discover ( const Interface  addr,
const unsigned  browseTime 
)

Discover all announced key/value pairs.

Parameters
addrthe scope of the discovery
browseTimethe browse time, in milliseconds, to wait for new records.
Returns
all instance names found during discovery.
See also
beginBrowsing(), browse(), endBrowsing()
Version
1.1
SERVUS_API void servus::Servus::endBrowsing ( )

Stop a discovery process and return all results.

Version
1.1
SERVUS_API const std::string& servus::Servus::get ( const std::string &  key) const
Returns
the value to the given (to be) announced key.
Version
1.1
SERVUS_API const std::string& servus::Servus::get ( const std::string &  instance,
const std::string &  key 
) const
Returns
the value of the given key and instance.
Version
1.1
SERVUS_API Strings servus::Servus::getInstances ( ) const
Returns
all instances found during the last discovery.
Version
1.1
SERVUS_API Strings servus::Servus::getKeys ( ) const
Returns
all (to be) announced keys.
Version
1.1
SERVUS_API Strings servus::Servus::getKeys ( const std::string &  instance) const
Returns
all keys discovered on the given instance.
Version
1.1
SERVUS_API const std::string& servus::Servus::getName ( ) const
Returns
the service name.
Version
1.1
SERVUS_API bool servus::Servus::isAnnounced ( ) const
Returns
true if the local data is announced.
Version
1.1
static SERVUS_API bool servus::Servus::isAvailable ( )
static
Returns
true if a usable implementation is available.
SERVUS_API bool servus::Servus::isBrowsing ( ) const
Returns
true if the local data is browsing.
Version
1.1
SERVUS_API void servus::Servus::removeListener ( Listener listener)

Remove a listener to stop invokation on its supported callbacks.

Parameters
listenerthe listener to be removed, must not be nullptr
Version
1.2
SERVUS_API void servus::Servus::set ( const std::string &  key,
const std::string &  value 
)

Set a key/value pair to be announced.

Keys should be at most eight characters, and values are truncated to 255 characters. The total length of all keys and values cannot exceed 65535 characters. Setting a value on an announced service causes an update which needs some time to propagate after this function returns, that is, calling discover() immediately afterwards will very likely not contain the new key/value pair.

Version
1.1
SERVUS_API void servus::Servus::withdraw ( )

Stop announcing the registered key/value pairs.

Version
1.1

Friends And Related Function Documentation

SERVUS_API std::ostream& operator<< ( std::ostream &  ,
const Servus  
)
friend

Output the servus instance in human-readable format.


The documentation for this class was generated from the following file: