hmbdc
simplify-high-performance-messaging-programming
chat.cpp
//this is to show how to use hmbdc to write a simple group chat application
//the app join a chat group and start to have group chat
//to run:
//./chatter local-ip chat-group-name my-name
//to build:
//g++ chat.cpp -g -std=c++1y -Wall -Werror -pthread -Ipath-to-hmbdc-lib-include path-to-hmbdc-lib/libhmbdc.a /usr/local/lib/libboost_regex.a /usr/local/lib/libboost_system.a /usr/local/lib/libboost_iostreams.a -lpthread -lrt -o /tmp/chat
//
#include "hmbdc/app/tcpcast/NetContext.hpp" //use tcpcast for communication
#include <iostream>
#include <string>
#include <memory>
#include <unistd.h>
using namespace std;
using namespace hmbdc::app;
//this is the message going back and forth carrying text conversations - 1000 char max
struct ChatMessage
: hasTag<1001> { //each message needs a unique tag - 16 bit user tag starting from 1001, 0-1000 is reserved
char id[16]; //chatter
char msg[1000]; //1000 char max per chat message
};
struct Chatter
: Client<Chatter, ChatMessage> {
Chatter(char const* id)
: id_(id){}
void handleMessageCb(ChatMessage const& m) {
if (id_ != m.id) {
cout << m.id << ": " << m.msg << endl;
}
}
private:
string id_;
};
int main(int argc, char** argv) {
using namespace std;
if (argc != 4) {
cerr << argv[0] << " local-ip chat-group-name my-name" << endl;
cerr << "multicast should be enabled on local-ip network" << endl;
return -1;
}
auto ifaceAddr = argv[1];
auto chatGroup = argv[2];
auto myId = argv[3];
//! [create NetContext with initial tx/rx capabilities]
Config config; //other config values are default
config.put("ifaceAddr", ifaceAddr);//which interface to use for communication
config.put("loopback", true); //could be chatting on the same machine
Context<sizeof(ChatMessage)> ctx; //large enough to hold ChatMessage's
//create NetContext with initial tx/rx capabilities, and listen to the default topic "_"
//received network messages goes to ctx. this launches a thread to power the above engines
SingletonGuardian<tcpcast::NetContext> g(ctx, &config); //RAII for tcpcast::NetContext resources
//! [create NetContext with initial tx/rx capabilities]
auto& net = tcpcast::NetContext::instance();
ctx.start(1 //start ctx with just 1 thread in the pool to power Chatter below
, 0x02); //pin the pool thread on second core
Chatter chatter(myId);
ctx.addToPool(chatter); //add the chatter client too
//now the network is set up
//subscribe to the topic
//and get a sender for the topic
Topic t(chatGroup);
net.listenTo(t);
auto s = net.getSender(t);
//we can read the user's input and send messages out now
string line;
ChatMessage m;
strncpy(m.id, myId, sizeof(m.id));
cout << "start type a message" << endl;
cout << "ctrl-d to terminate" << endl;
while(getline(cin, line)) {
strncpy(m.msg, line.c_str(), sizeof(m.msg));
s->send(m);
}
net.stopListenTo(t);
}