Created
April 29, 2017 04:24
-
-
Save OlegJakushkin/4ed9afb23878e1b555578807e62fe9af to your computer and use it in GitHub Desktop.
This file contains hidden or 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
//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