Now that we have correctly build and installed the n3rv library, we will start to code.
The goal here is to create a simple program that will instanciate 2 nodes and a service controller. Node 1 will continuously broadcast the “Hello World” string. Node 2 will connect to Node1’s broadcast stream and display data on its stdout as soon as they are received.
So we’ll start by creating a new blank file called “hello.cpp” and edit it
The first step is to add in our hello.cpp the required headers for n3rv. Let’s do this:
#include <n3rv/n3rvcommon.hpp>
#include <n3rv/n3rvservice.hpp>
#include <n3rv/n3rvservicecontroller.hpp>
The Next step will be to create a new service class. its role will just be to:
/* We declare our new class inheriting from n3rv::service. */
class hellosend: public n3rv::service {
using n3rv::service::service;
public:
n3rv::qhandler* hello;
int initialize() {
//Sets a global identifier for service node.
this->set_uid("com.hellosend.hello1");
//creates a new ZMQ socket binding of type PUBLISH
hello = this->bind("hello","0.0.0.0", ZMQ_PUB);
}
/* We add some code in the main loop to continually send "Hello World"
on the pub socket */
void hkloop() {
n3rv::message msg;
msg.payload = "Hello World";
this->send(hello,msg,0);
}
};
Then we will declare a simple receiver class which has the following behaviour:
class helloreceive: public n3rv::service {
using n3rv::service::service;
public:
n3rv::qhandler* hello;
int initialize() {
this->set_uid("com.hellorecv.recv1");
/* We connect to the sender */
hello = this->connect("com.hellosend.*.hello",ZMQ_SUB);
/* We attach reveive callback to connection */
this->attach(hello, hello_recv);
}
/*data receive callback.*/
static void* hello_recv(void* objref, zmq::message_t* zmsg) {
helloreceive* self = (helloreceive*) objref;
n3rv::message msg = n3rv::parse_msg(zmsg);
/* We log received data */
self->ll->log(n3rv::LOGLV_NOTICE, msg.payload + " from " + self->hello->peer_uid);
}
};
Finally we will add a main() function that will instanciate both one hellosend and one helloreceive node, along with a service controller and let them all run()
int main() {
/* We create a new logger object */
n3rv::logger* ll = new n3rv::logger(n3rv::LOGLV_DEBUG);
/* Then we tell it to perform stdout display */
ll->add_dest("stdout");
/* We asynchronously start a new service controller */
n3rv::start_controller("0.0.0.0",10001,ll);
/* We instanciate a new hellosend node */
hellosend hs("127.0.0.1",10001,ll);
/* We initialize it and run it asynchronously */
hs.initialize();
hs.run_async();
/* We instanciate a new helloreceive node. */
helloreceive hr("127.0.0.1",10001,ll);
/* We initialize then run it */
hr.initialize();
hr.run();
}
The full hello.cpp code source is then the following:
#include <n3rv/n3rvcommon.hpp>
#include <n3rv/n3rvservice.hpp>
#include <n3rv/n3rvservicecontroller.hpp>
class hellosend: public n3rv::service {
using n3rv::service::service;
public:
n3rv::qhandler* hello;
int initialize() {
this->set_uid("com.hellosend.hello1");
hello = this->bind("hello","0.0.0.0", ZMQ_PUB);
}
void hkloop() {
n3rv::message msg;
msg.payload = "Hello World";
this->send(hello,msg,0);
}
};
class helloreceive: public n3rv::service {
using n3rv::service::service;
public:
n3rv::qhandler* hello;
int initialize() {
this->set_uid("com.hellorecv.recv1");
hello = this->connect("com.hellosend.*.hello",ZMQ_SUB);
this->attach(hello, hello_recv);
}
//data receive callback.
static void* hello_recv(void* objref, zmq::message_t* zmsg) {
helloreceive* self = (helloreceive*) objref;
n3rv::message msg = n3rv::parse_msg(zmsg);
self->ll->log(n3rv::LOGLV_NOTICE, msg.payload + " from " + self->hello->peer_uid);
}
};
int main() {
n3rv::logger* ll = new n3rv::logger(n3rv::LOGLV_DEBUG);
ll->add_dest("stdout");
n3rv::start_controller("0.0.0.0",10001,ll);
hellosend hs("127.0.0.1",10001,ll);
hs.initialize();
hs.run_async();
helloreceive hr("127.0.0.1",10001,ll);
hr.initialize();
hr.run();
}
Now that we wrote our program, it’s time to compile and run it:
g++ hello.cpp -o hello -ln3rv -lzmq -lpthread && ./hello
If compiling succeded, here’s what you should see: