Last active
April 14, 2021 20:46
-
-
Save eduardoaugustojulio/eba88a6a1ef6555f9b076942f9c2fce7 to your computer and use it in GitHub Desktop.
C++ class that publish a service with message in the network using avahi msdn library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <vector> | |
#include "publisher.h" | |
int main(const int argc, const char **argv) | |
{ | |
std::vector<std::string> message; | |
for(auto i = 0; i < 10; i++) | |
message.push_back("test message " + std::to_string(i)); | |
libpublisher::publisher new_publish("test service", 8080, "_http._tcp", message); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <iostream> | |
#include <string> | |
#include <cstring> | |
#include <avahi-client/client.h> | |
#include <avahi-client/publish.h> | |
#include <avahi-common/alternative.h> | |
#include <avahi-common/simple-watch.h> | |
#include <avahi-common/malloc.h> | |
#include <avahi-common/error.h> | |
#include <avahi-common/timeval.h> | |
#include "publisher.h" | |
static AvahiEntryGroup *group; | |
static AvahiSimplePoll *poll; | |
static const char *name; | |
std::string service_type, message; | |
AvahiStringList *dns_message; | |
int port_number; | |
void publisher::entry_group_callback(AvahiEntryGroup * _group, AvahiEntryGroupState _state, void * userdata) | |
{ | |
group = _group; | |
switch(_state){ | |
case AVAHI_ENTRY_GROUP_FAILURE: | |
std::cerr << "ENTRY GROUP FAILURE: " << avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(_group))) << std::endl; | |
avahi_simple_poll_quit(poll); | |
break; | |
case AVAHI_ENTRY_GROUP_COLLISION : | |
case AVAHI_ENTRY_GROUP_ESTABLISHED : | |
case AVAHI_ENTRY_GROUP_UNCOMMITED: | |
case AVAHI_ENTRY_GROUP_REGISTERING: | |
; | |
break; | |
} | |
} | |
void publisher::create_services(AvahiClient * _client) | |
{ | |
if ((!group)&&(!(group = avahi_entry_group_new(_client, entry_group_callback, NULL)))) | |
{ | |
std::cout << "avahi_entry_group_new() failed: " << avahi_strerror(avahi_client_errno(_client)) << std::endl; | |
avahi_simple_poll_quit(poll); | |
} | |
if (avahi_entry_group_is_empty(group)) | |
{ | |
auto ret = avahi_entry_group_add_service_strlst(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name, service_type.c_str() , NULL, NULL, port_number, dns_message); | |
if (ret < 0) | |
{ | |
if (ret == AVAHI_ERR_COLLISION){ | |
create_services(_client); | |
} | |
std::cerr << "Failed to add _ipp._tcp service:" << avahi_strerror(ret) << std::endl; | |
avahi_simple_poll_quit(poll); | |
} | |
if ((ret = avahi_entry_group_commit(group)) < 0) { | |
std::cerr << "Failed to commit entry group: " << avahi_strerror(ret) << std::endl; | |
avahi_simple_poll_quit(poll); | |
} | |
} | |
return; | |
} | |
void publisher::client_callback(AvahiClient *_client, AvahiClientState _state, void *userdata) | |
{ | |
switch (_state) | |
{ | |
case AVAHI_CLIENT_S_RUNNING: | |
create_services(_client); | |
break; | |
case AVAHI_CLIENT_FAILURE: | |
std::cerr << "Client failure: " << avahi_strerror(avahi_client_errno(_client)) << std::endl; | |
avahi_simple_poll_quit(poll); | |
break; | |
case AVAHI_CLIENT_S_COLLISION: | |
case AVAHI_CLIENT_S_REGISTERING: | |
if (group) avahi_entry_group_reset(group); | |
break; | |
case AVAHI_CLIENT_CONNECTING: | |
; | |
break; | |
} | |
} | |
void publisher::treat_collision(AvahiClient * _client) | |
{ | |
char *n; | |
n = avahi_alternative_service_name(name); | |
avahi_free((void *)name); | |
name = n; | |
fprintf(stderr, "Service name collision, renaming service to '%s'\n", name); | |
avahi_entry_group_reset(group); | |
create_services(_client); | |
return; | |
} | |
void publisher::publish_avahi_service(const char *_service_name, const int _port_number, const char *_service_type) | |
{ | |
name = _service_name; | |
port_number = _port_number; | |
service_type = _service_type; | |
poll = avahi_simple_poll_new(); | |
if(poll){ | |
int error; | |
AvahiClient *client = avahi_client_new(avahi_simple_poll_get(poll), static_cast<AvahiClientFlags>(0), client_callback, NULL, &error); | |
if(client){ | |
avahi_simple_poll_loop(poll); | |
avahi_client_free(client); | |
} else { | |
std::cout << "FAILED TO CREATE AVAHI CLIENT OBJECT: " << avahi_strerror(error) << std::endl; | |
avahi_simple_poll_free(poll); | |
} | |
} else { | |
std::cout << "FAILED TO CREATE AVAHI SIMPLE POLL OBJECT: " << std::endl; | |
} | |
} | |
publisher::publisher(const std::string &service_name, const int &port_number, const std::string &service_type, std::vector<std::string> &message) | |
{ | |
dns_message = avahi_string_list_new("version = V1.13", NULL); | |
for(auto i = 0; i < message.size(); i++) | |
dns_message = avahi_string_list_add(dns_message,std::string("message"+std::to_string(i)+"="+message.at(i)).c_str()); | |
publish_avahi_service(service_name.c_str(), port_number, service_type.c_str()); | |
} | |
publisher::~publisher() | |
{ | |
avahi_simple_poll_free(poll); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _PUBLISHER_H | |
#define _PUBLISHER_H | |
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <avahi-client/client.h> | |
#include <avahi-client/publish.h> | |
#include <avahi-common/alternative.h> | |
#include <avahi-common/simple-watch.h> | |
#include <avahi-common/malloc.h> | |
#include <avahi-common/error.h> | |
#include <avahi-common/timeval.h> | |
namespace libpublisher | |
{ | |
class publisher | |
{ | |
private: | |
static void entry_group_callback(AvahiEntryGroup *_group, AvahiEntryGroupState _state, void *userdata); | |
static void create_services(AvahiClient *_client); | |
static void client_callback(AvahiClient *_client, AvahiClientState _state, void *userdata); | |
void treat_collision(AvahiClient *_client); | |
public: | |
void publish_avahi_service(const char *_service_name, const int _port_number, const char *_service_type); | |
publisher(const std::string &service_name, const int &port_number, const std::string &service_type, std::vector<std::string> & message); | |
~publisher(); | |
}; | |
} | |
#endif //_PUBLISHER_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment