Created
February 17, 2021 10:23
-
-
Save pulsejet/0a60e7f28f9ad36148a89b534e5fc368 to your computer and use it in GitHub Desktop.
Chat application serving on separate prefix on ndn-svs
This file contains 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
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */ | |
/* | |
* Copyright (c) 2012-2021 University of California, Los Angeles | |
* | |
* This file is part of ndn-svs, synchronization library for distributed realtime | |
* applications for NDN. | |
* | |
* ndn-svs library is free software: you can redistribute it and/or modify it under the | |
* terms of the GNU Lesser General Public License as published by the Free Software | |
* Foundation, in version 2.1 of the License. | |
* | |
* ndn-svs library is distributed in the hope that it will be useful, but WITHOUT ANY | |
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. | |
*/ | |
#include <iostream> | |
#include <string> | |
#include <thread> | |
#include <vector> | |
#include <ndn-svs/socket.hpp> | |
#include <ndn-cxx/ims/in-memory-storage-persistent.hpp> | |
class Options | |
{ | |
public: | |
Options() : prefix("/ndn/svs") {} | |
public: | |
std::string prefix; | |
std::string m_id; | |
}; | |
class Program | |
{ | |
public: | |
Program(const Options &options) | |
: m_options(options) | |
{ | |
m_registeredDataPrefix = | |
face.setInterestFilter(getDataName(m_options.m_id, 0).getPrefix(-1), | |
[this] (const ndn::Name& prefix, const ndn::Interest& interest) { | |
auto data = m_ims.find(interest); | |
if (data != nullptr) | |
face.put(*data); | |
}, | |
[] (const ndn::Name& prefix, const std::string& msg) {}); | |
m_logic = std::make_shared<ndn::svs::Logic>( | |
face, | |
keychain, | |
ndn::Name(m_options.prefix), | |
std::bind(&Program::onMissingData, this, _1), | |
"dGhpcyBpcyBhIHNlY3JldCBtZXNzYWdl", | |
ndn::Name(m_options.m_id).toUri()); | |
std::cout << "SVS client stared:" << m_options.m_id << std::endl; | |
} | |
void | |
run() | |
{ | |
std::thread thread_svs([this] { face.processEvents(); }); | |
std::string init_msg = "User " + m_options.m_id + " has joined the groupchat"; | |
publishMsg(init_msg); | |
std::string userInput = ""; | |
while (true) { | |
std::getline(std::cin, userInput); | |
publishMsg(userInput); | |
} | |
thread_svs.join(); | |
} | |
private: | |
void | |
onMissingData(const std::vector<ndn::svs::MissingDataInfo>& v) | |
{ | |
for (size_t i = 0; i < v.size(); i++) | |
{ | |
for (ndn::svs::SeqNo s = v[i].low; s <= v[i].high; ++s) | |
{ | |
ndn::svs::NodeID nid = v[i].session; | |
ndn::Interest interest(getDataName(nid, s)); | |
face.expressInterest(interest, [nid] (const ndn::Interest& interest, const ndn::Data& data) | |
{ | |
size_t data_size = data.getContent().value_size(); | |
std::string content_str((char *)data.getContent().value(), data_size); | |
content_str = nid + " : " + content_str; | |
std::cout << content_str << std::endl; | |
}, nullptr, nullptr); | |
} | |
} | |
} | |
void | |
publishMsg(std::string msg) | |
{ | |
ndn::svs::SeqNo seq = m_logic->getSeqNo(); | |
ndn::Name name = getDataName(m_options.m_id, seq + 1); | |
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(name); | |
data->setContent(reinterpret_cast<const uint8_t*>(msg.c_str()), msg.size()); | |
data->setFreshnessPeriod(ndn::time::milliseconds(1000)); | |
keychain.sign(*data); | |
m_ims.insert(*data); | |
m_logic->updateSeqNo(seq + 1); | |
} | |
ndn::Name | |
getDataName(ndn::svs::NodeID nid, ndn::svs::SeqNo seq) | |
{ | |
return ndn::Name(nid).append(ndn::Name(m_options.prefix)) | |
.appendNumber(seq); | |
} | |
public: | |
const Options m_options; | |
ndn::Face face; | |
ndn::KeyChain keychain; | |
std::shared_ptr<ndn::svs::Logic> m_logic; | |
ndn::InMemoryStoragePersistent m_ims; | |
ndn::ScopedRegisteredPrefixHandle m_registeredDataPrefix; | |
}; | |
int | |
main(int argc, char **argv) | |
{ | |
if (argc != 2) { | |
std::cout << "Usage: client <prefix>" << std::endl; | |
exit(1); | |
} | |
Options opt; | |
opt.m_id = argv[1]; | |
Program program(opt); | |
program.run(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment