Skip to content

Instantly share code, notes, and snippets.

@OlegJakushkin
Created April 29, 2017 04:24
Show Gist options
  • Save OlegJakushkin/4ed9afb23878e1b555578807e62fe9af to your computer and use it in GitHub Desktop.
Save OlegJakushkin/4ed9afb23878e1b555578807e62fe9af to your computer and use it in GitHub Desktop.
//datastructures+serialization+req-rep
#include <iostream>
#include <string>
#include <pico.h>
#include <zmq_addon.hpp>
#include <atomic>
#include <thread>
using namespace std;
using namespace zmq;
atomic<bool> stop;
////////////////////// Buiseness logic data
struct record {
string title;
string author;
int pages;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("title", title);
ar & picojson::convert::member("author", author);
ar & picojson::convert::member("pages", pages);
}
record(){}
record(string title, string author, int pages) : title(title), author(author), pages(pages){}
};
struct shelf {
std::vector<record> books;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("books", books);
}
};
/////////////////////// Messaging logic data
struct message {
string clientId;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("id", clientId);
}
};
struct request : message {};
struct reply : message {};
struct event : message {};
enum searchType {
TITLE =0,
AUTHOR = 20
};
struct readRequest : request {
string plee;
searchType type;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("type", type);
ar & picojson::convert::member("plee", plee);
request::json(ar);
}
};
namespace picojson {
namespace convert {
template<> struct value_converter<searchType> {
static value to_value(searchType v) {
return value(static_cast<double>(v));
}
static void from_value(value const& ov, searchType& v) {
if ( ov.is<double>() ) v = searchType(static_cast<int>(ov.get<double>()));
}
};
}
}
struct putRequest : request {
record book;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("record", book);
request::json(ar);
}
};
struct readResponse : reply {
bool status;
record book;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("status", status);
ar & picojson::convert::member("record", book);
reply::json(ar);
}
};
struct putResponse : reply {
bool status;
template<class Archive>
void json(Archive & ar)
{
ar & picojson::convert::member("status", status);
reply::json(ar);
}
};
////////////////////// App
int main() {
context_t ctx;
auto server = [&]() {
shelf s;
record r1("road", "me", 190);
record r2("path", "me", 333);
s.books.push_back(r1);
s.books.push_back(r2);
socket_t socket(ctx, ZMQ_REP);
socket.bind("tcp://*:5555");
while(!stop) {
message_t identity;
message_t req;
socket.recv(&identity);
string requestType(identity.data<char>(), identity.size());
socket.recv(&req);
string request(req.data<char>(), req.size());
cout << request << endl;
string reply;
if(requestType == "put") {
putResponse response;
putRequest releaseQuery;
picojson::convert::from_string(request, releaseQuery);
s.books.push_back(releaseQuery.book);
response.status = true;
reply = picojson::convert::to_string(response);
} else if(requestType == "get") {
readResponse response;
readRequest readQuery;
picojson::convert::from_string(request, readQuery);
auto it = find_if(s.books.begin(), s.books.end(), [&](record & current) {
bool result = false;
switch(readQuery.type) {
case TITLE:
result = current.title == readQuery.plee;
break;
case AUTHOR:
result = current.author == readQuery.plee;
break;
default: break;
}
return result;
});
if(it != s.books.end()) {
response.status = true;
response.book = *it;
} else {
response.status = false;
}
reply = picojson::convert::to_string(response);
}
message_t rep(reply.data(), reply.size());
socket.send(rep);
}
};
auto client = [&]() {
socket_t socket(ctx, ZMQ_REQ);
socket.connect("tcp://127.0.0.1:5555");
while(!socket.connected()) {
this_thread::sleep_for(chrono::milliseconds(100));
}
int action = 1;
record atHand;
while(!stop) {
string requestType;
string requestContent;
if(action == 1) {
requestType = "get";
} else {
requestType = "put";
}
message_t identity(requestType.data(), requestType.size());
if(action == 1) {
readRequest read;
read.type = AUTHOR;
read.plee = "me";
requestContent = picojson::convert::to_string(read);
} else {
putRequest put;
put.book = atHand;
requestContent = picojson::convert::to_string(put);
}
message_t msg(requestContent.data(), requestContent.size());
socket.send(identity, ZMQ_SNDMORE);
socket.send(msg);
message_t rep;
socket.recv(&rep);
string reply(rep.data<char>(), rep.size());
cout << "received: " << reply << endl;
if(action == 1) {
readResponse response;
picojson::convert::from_string(reply, response);
if(response.status == true) {
atHand = response.book;
}
}
if(++action > 2) {
action =1;
}
}
};
thread s(server);
thread c(client);
while(!stop) {
string exit;
cin >> exit;
if(exit == "exit") {
stop = true;
} else {
cout << "enter 'exit' to quit" << endl;
}
}
s.join();
c.join();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment