Part 3: Connecting to the Marlin Network
Step 1 - Download and run a Goldfish node
For the purposes of this tutorial, we will use an executable called Goldfish that emulates the Marlin Network locally.
The executable is available here for Linux and here for macOS.
After downloading the executable to the build
folder, open a new console and run it using
$ ./goldfish # You might have given it a different name during download
You might have to change permissions on the file to make it executable using
$ chmod +x ./goldfish # Add sudo in the beginning if necessary
You might get a verification error on macOS 10.15 that looks something like this:
To fix this, navigate to System Preferences -> Security & Privacy -> General and click "Allow Anyway" against the goldfish executable:
Check that it prints the IP and ports that it is using in the console.
Step 2 - Set up a multicast client
Include the header for the multicast client and the relevant namespaces using
#include <marlin/multicast/DefaultMulticastClient.hpp>
using namespace marlin::multicast;
using namespace marlin::net;
Before we create the client, we need to create a delegate that is notified of important events by the client (e.g. new messages). See the reference documentation for further information on the events that can be listened to.
class MulticastDelegate {
public:
void did_recv_message(
DefaultMulticastClient<MulticastDelegate> &client,
Buffer &&message,
Buffer &&witness,
std::string &channel,
uint64_t message_id
) {}
void did_subscribe(
DefaultMulticastClient<MulticastDelegate> &client,
std::string &channel
) {
SPDLOG_INFO("Did subscribe to channel {}", channel);
}
void did_unsubscribe(
DefaultMulticastClient<MulticastDelegate> &client,
std::string &channel
) {
SPDLOG_INFO("Did unsubscribe from channel {}", channel);
}
};
Currently, the delegate ignores all messages and prints subscription/unsubscription logs.
Inside the main function, create a keypair that is used by the client for identification.
uint8_t static_sk1[crypto_box_SECRETKEYBYTES];
uint8_t static_pk1[crypto_box_PUBLICKEYBYTES];
crypto_box_keypair(static_pk1, static_sk1);
Inside the main function, initialize a multicast client and delegate. The client can be customized by providing options during initialization. For further information on the available options, please refer to the reference documentation.
MulticastDelegate del;
DefaultMulticastClientOptions clop1 {
static_sk1, // Secret key
{"goldfish"}, // Pubsub channels
"127.0.0.1:9002" // Beacon address from the goldfish node
};
DefaultMulticastClient<MulticastDelegate> cl1(clop1);
cl1.delegate = &del;
Step 3 - Run the event loop
The Marlin Multicast SDK is fully asynchronous and uses event loops to acheive this.
Run the event loop using
return DefaultMulticastClient<MulticastDelegate>::run_event_loop();
Once you have followed the above instructions, you should have a main.cpp
that looks like this:
#include <marlin/multicast/DefaultMulticastClient.hpp>
using namespace marlin::multicast;
using namespace marlin::net;
class MulticastDelegate {
public:
void did_recv_message(
DefaultMulticastClient<MulticastDelegate> &client,
Buffer &&message,
Buffer &&witness,
std::string &channel,
uint64_t message_id
) {}
void did_subscribe(
DefaultMulticastClient<MulticastDelegate> &client,
std::string &channel
) {
SPDLOG_INFO("Did subscribe to channel {}", channel);
}
void did_unsubscribe(
DefaultMulticastClient<MulticastDelegate> &client,
std::string &channel
) {
SPDLOG_INFO("Did unsubscribe from channel {}", channel);
}
};
int main() {
uint8_t static_sk1[crypto_box_SECRETKEYBYTES];
uint8_t static_pk1[crypto_box_PUBLICKEYBYTES];
crypto_box_keypair(static_pk1, static_sk1);
MulticastDelegate del;
DefaultMulticastClientOptions clop1 {
static_sk1,
{"goldfish"},
"127.0.0.1:9002"
};
DefaultMulticastClient<MulticastDelegate> cl1(clop1);
cl1.delegate = &del;
return DefaultMulticastClient<MulticastDelegate>::run_event_loop();
}
This sets up a multicast client that connects to the Marlin Network on 127.0.0.1:9002
can send and receive on the goldfish
channel. The client automatically talks to the Goldfish node we ran above and sets up PubSub on the given channel. The client calls the corresponding functions in the delegate to notify it of any significant events.
Step 4 - Build and run executable
Build using
$ cmake .. -DCMAKE_BUILD_TYPE=Release
$ make
and run using
$ ./tutorial
Building should have worked and the executable should run. You should see subscription related logs printed here indicating a successful connection between the client and the Marlin Network.
Conclusion
In this part, we learnt how to use the Marlin Multicast SDK to connect to the Marlin Network. In the next part we will learn how to use the Marlin Multicast SDK to send and receive messages using the Marlin Network.