[DEV] add future to correct manage of the async...

This commit is contained in:
Edouard DUPIN 2016-05-26 22:12:37 +02:00
parent 5efffd975f
commit e37b00c2d3
14 changed files with 462 additions and 274 deletions

View File

@ -152,6 +152,19 @@ namespace jus {
}
ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service) {
ejson::Object obj;
if (_service.size() != 0) {
obj.add("service", ejson::String(_service));
}
obj.add("call", ejson::String(_functionName));
obj.add("id", ejson::Number(_transactionId));
return obj;
}
void jus::createParam(ejson::Object& _obj) {
// Finish recursive parse ...
}
const std::string& jus::AbstractFunction::getName() const {
return m_name;
}

View File

@ -47,5 +47,148 @@ namespace jus {
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service="");
void createParam(ejson::Object& _obj);
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
if (_param == nullptr) {
array.add(ejson::String());
} else {
array.add(ejson::String(_param));
}
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::String(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Boolean(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::String(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (const auto& it : _param) {
array2.add(ejson::Boolean(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args) {
if (_obj.valueExist("param") == false) {
_obj.add("param", ejson::Array());
}
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
ejson::Object createCall(uint64_t _transactionId, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
return callElem;
}
template<class... _ARGS>
ejson::Object createCallService(uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceName);
createParam(callElem, std::forward<_ARGS>(_args)...);
return callElem;
}
}

View File

@ -22,7 +22,37 @@ jus::Client::~Client() {
}
void jus::Client::onClientData(std::string _value) {
m_newData.push_back(std::move(_value));
ejson::Object obj(_value);
jus::FutureBase future;
{
uint64_t tid = etk::string_to_uint64_t(obj["id"].toString().get());
if (tid == 0) {
JUS_ERROR("call with no ID ==> error ...");
return;
}
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_pendingCall.begin();
while (it != m_pendingCall.end()) {
if (it->isValid() == false) {
it = m_pendingCall.erase(it);
continue;
}
if (it->getTransactionId() != tid) {
++it;
continue;
}
future = *it;
it = m_pendingCall.erase(it);
return;
}
}
if (future.isValid() == false) {
JUS_TODO("manage this event better ...");
m_newData.push_back(std::move(_value));
return;
}
// TODO : Call future ...
}
jus::ServiceRemote jus::Client::getService(const std::string& _name) {
@ -96,15 +126,8 @@ void jus::Client::disconnect() {
JUS_DEBUG("disconnect [STOP]");
}
ejson::Object jus::Client::createBaseCall(const std::string& _functionName, const std::string& _service) {
ejson::Object obj;
if (_service.size() != 0) {
obj.add("service", ejson::String(_service));
}
obj.add("call", ejson::String(_functionName));
obj.add("id", ejson::Number(m_id++));
obj.add("param", ejson::Array());
return obj;
uint64_t jus::Client::getId() {
return m_id++;
}
ejson::Object jus::Client::callJson(const ejson::Object& _obj) {
@ -118,3 +141,42 @@ ejson::Object jus::Client::callJson(const ejson::Object& _obj) {
JUS_VERBOSE("Call JSON [STOP]");
return ejson::Object(ret);
}
jus::FutureBase jus::Client::sendJson(uint64_t _transactionId, const ejson::Object& _obj) {
JUS_VERBOSE("Send JSON [START] ");
if (m_interfaceClient.isActive() == false) {
ejson::Object obj;
obj.add("error", ejson::String("NOT-CONNECTED"));
obj.add("error-help", ejson::String("Client interface not connected (no TCP)"));
return jus::FutureBase(_transactionId, true, obj);
}
jus::FutureBase tmpFuture(_transactionId);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_pendingCall.push_back(tmpFuture);
}
JUS_DEBUG("Send JSON '" << _obj.generateHumanString() << "'");
m_interfaceClient.write(_obj.generateMachineString());
JUS_VERBOSE("Send JSON [STOP]");
return tmpFuture;
}
namespace jus {
template<>
bool jus::Future<bool>::get() {
if (m_data == nullptr) {
return false;
}
ejson::Value val = m_data->m_returnData["return"];
if (val.exist() == false) {
JUS_WARNING("No Return value ...");
return false;
}
if (val.isBoolean() == false) {
JUS_WARNING("Wrong return Type get '" << val.getType() << " instead of 'Boolean'");
return false;
}
return val.toBoolean().get();
}
}

View File

@ -10,13 +10,127 @@
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/ServiceRemote.h>
#include <chrono>
#include <unistd.h>
namespace jus {
class FutureData {
public:
uint64_t m_transactionId;
bool m_isFinished;
ejson::Object m_returnData;
};
class FutureBase {
public: // TODO: Do it better ..
ememory::SharedPtr<jus::FutureData> m_data;
public:
FutureBase() {
m_data = nullptr;
}
FutureBase(uint64_t _transactionId) {
m_data = std::make_shared<jus::FutureData>();
if (m_data == nullptr) {
return;
}
m_data->m_transactionId = _transactionId;
m_data->m_isFinished = false;
}
FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData) {
m_data = std::make_shared<jus::FutureData>();
if (m_data == nullptr) {
return;
}
m_data->m_transactionId = _transactionId;
m_data->m_isFinished = _isFinished;
m_data->m_returnData = _returnData;
}
jus::FutureBase operator= (const jus::FutureBase& _base) {
m_data = _base.m_data;
return *this;
}
void setAnswer(const ejson::Object& _returnValue) {
if (m_data == nullptr) {
JUS_ERROR(" Not a valid future ...");
return;
}
m_data->m_returnData = _returnValue;
m_data->m_isFinished = true;
}
uint64_t getTransactionId() {
if (m_data == nullptr) {
return 0;
}
return m_data->m_transactionId;
}
bool hasError() {
if (m_data == nullptr) {
return true;
}
return m_data->m_returnData.valueExist("error");
}
std::string getErrorType() {
if (m_data == nullptr) {
return "NULL_PTR";
}
return m_data->m_returnData["error"].toString().get();
}
std::string getErrorHelp() {
if (m_data == nullptr) {
return "Thsi is a nullptr future";
}
return m_data->m_returnData["error-help"].toString().get();
}
bool isValid() {
return m_data != nullptr;
}
bool isFinished() {
if (m_data == nullptr) {
return true;
}
return m_data->m_isFinished;
}
void wait() {
while (isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000);
}
}
bool waitFor(std::chrono::microseconds _delta) {
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
while ( std::chrono::steady_clock::now() - start < _delta
&& isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000);
}
return isFinished();
}
bool waitUntile(std::chrono::steady_clock::time_point _endTime) {
while ( std::chrono::steady_clock::now() < _endTime
&& isFinished() == false) {
// TODO : Do it better ... like messaging/mutex_locked ...
usleep(10000);
}
return isFinished();
}
};
template<class JUS_RETURN>
class Future : public jus::FutureBase {
public:
jus::Future<JUS_RETURN>& operator= (const jus::FutureBase& _base) {
m_data = _base.m_data;
return *this;
}
JUS_RETURN get();
};
class Client : public eproperty::Interface {
friend class ServiceRemote;
public:
eproperty::Value<std::string> propertyIp;
eproperty::Value<uint16_t> propertyPort;
std::mutex m_mutex;
std::vector<jus::FutureBase> m_pendingCall;
private:
jus::TcpString m_interfaceClient;
uint32_t m_id;
@ -39,105 +153,21 @@ namespace jus {
void onClientData(std::string _value);
std::string asyncRead();
ejson::Object callJson(const ejson::Object& _obj);
ejson::Object createBaseCall(const std::string& _functionName, const std::string& _service="");
void createParam(ejson::Object& _obj) {
// Finish recursive parse ...
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
if (_param == nullptr) {
array.add(ejson::String());
} else {
array.add(ejson::String(_param));
}
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::String(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Boolean(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::String(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (const auto& it : _param) {
array2.add(ejson::Boolean(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
jus::FutureBase sendJson(uint64_t _transactionId, const ejson::Object& _obj);
public:
uint64_t getId();
template<class JUS_RETURN, class... _ARGS>
jus::Future<JUS_RETURN> callAsync(const std::string& _functionName, _ARGS&&... _args) {
uint64_t id = getId();
ejson::Object callElem = jus::createCall(id, _functionName, std::forward<_ARGS>(_args)...);
jus::Future<JUS_RETURN> out = sendJson(id, callElem);
return out;
}
template<class... _ARGS>
void call(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -145,8 +175,7 @@ namespace jus {
}
template<class... _ARGS>
int32_t call_i(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -164,8 +193,7 @@ namespace jus {
}
template<class... _ARGS>
double call_d(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -183,8 +211,7 @@ namespace jus {
}
template<class... _ARGS>
std::string call_s(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -202,8 +229,7 @@ namespace jus {
}
template<class... _ARGS>
bool call_b(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -221,8 +247,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<int32_t> call_vi(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -252,8 +277,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<double> call_vd(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -283,8 +307,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<std::string> call_vs(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -314,8 +337,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<bool> call_vb(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCall(getId(), _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);

View File

@ -75,7 +75,7 @@ void jus::GateWay::newService(enet::Tcp _connection) {
void jus::GateWay::newClient(enet::Tcp _connection) {
JUS_WARNING("New TCP connection (client)");
ememory::SharedPtr<jus::GateWayClient> tmp = std::make_shared<jus::GateWayClient>(std::move(_connection), this);
tmp->start(m_clientUID++);
tmp->start(m_clientUID++, m_clientUID++);
m_clientList.push_back(tmp);
}
@ -122,7 +122,7 @@ void jus::GateWay::answer(uint64_t _userSessionId, ejson::Object _data) {
if (it == nullptr) {
continue;
}
if (it->getId() != std::abs(_userSessionId)) {
if (it->checkId(_userSessionId) == false) {
continue;
}
it->returnMessage(_data);

View File

@ -12,7 +12,7 @@ namespace jus {
class TcpServerInput;
class GateWay : public eproperty::Interface {
private:
size_t m_clientUID;
uint64_t m_clientUID;
private:
std::vector<ememory::SharedPtr<jus::GateWayService>> m_serviceList; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<jus::GateWayClient>> m_clientList; //!< List of all Client interface with their own connection

View File

@ -10,6 +10,8 @@
#include <jus/GateWay.h>
#include <unistd.h>
#include <jus/AbstractFunction.h>
jus::GateWayClient::GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayInterface) :
m_state(jus::GateWayClient::state::unconnect),
m_gatewayInterface(_gatewayInterface),
@ -28,8 +30,9 @@ jus::GateWayClient::~GateWayClient() {
JUS_INFO("-------------------");
}
void jus::GateWayClient::start(size_t _uid) {
void jus::GateWayClient::start(uint64_t _uid, uint64_t _uid2) {
m_uid = _uid;
m_uid2 = _uid2;
m_state = jus::GateWayClient::state::connect;
m_interfaceClient.connect(this, &jus::GateWayClient::onClientData);
m_interfaceClient.connect(true);
@ -48,7 +51,7 @@ void jus::GateWayClient::stop() {
if (m_userService != nullptr) {
ejson::Object linkService;
linkService.add("event", ejson::String("delete"));
m_userService->SendData(-m_uid, linkService);
m_userService->SendData(m_uid2, linkService);
m_userService = nullptr;
}
m_listConnectedService.clear();
@ -87,6 +90,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
return;
}
switch (m_state) {
case jus::GateWayClient::state::disconnect:
case jus::GateWayClient::state::unconnect:
{
JUS_ERROR("Must never appear");
@ -101,19 +105,23 @@ void jus::GateWayClient::onClientData(std::string _value) {
}
std::string call = data["call"].toString().get();
if (call == "connectToUser") {
m_userConnectionName = data["connect-to-user"].toString().get();
JUS_WARNING("[" << m_uid << "] Set client connect to user : '" << m_userConnectionName << "'");
m_userService = m_gatewayInterface->get("system-user");
if (m_userService == nullptr) {
protocolError("Gateway internal error 'No user interface'");
m_userConnectionName = data["param"].toArray()[0].toString().get();
if (m_userConnectionName == "") {
protocolError("Call connectToUser with no parameter 'user'");
} else {
ejson::Object linkService;
linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName));
m_userService->SendData(-m_uid, linkService);
m_state = jus::GateWayClient::state::userIdentify;
returnBool(transactionId, true);
JUS_WARNING("[" << m_uid << "] Set client connect to user : '" << m_userConnectionName << "'");
m_userService = m_gatewayInterface->get("system-user");
if (m_userService == nullptr) {
protocolError("Gateway internal error 'No user interface'");
} else {
ejson::Object linkService;
linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName));
m_userService->SendData(m_uid2, linkService);
m_state = jus::GateWayClient::state::userIdentify;
returnBool(transactionId, true);
}
}
return;
}
@ -143,15 +151,38 @@ void jus::GateWayClient::onClientData(std::string _value) {
if (_data["return"].toBoolean().get() == true) {
m_clientName = clientName;
m_clientgroups.clear();
// TODO : Update all service name and group ...
returnBool(transactionId, true);
ejson::Object gwCall;
int32_t tmpID = m_transactionLocalId--;
gwCall.add("id", ejson::Number(tmpID));
gwCall.add("call", ejson::String("getGroups"));
ejson::Array gwParam;
gwParam.add(ejson::String(clientName));
gwCall.add("param", gwParam);
{
std::unique_lock<std::mutex> lock(m_mutex);
m_actions.push_back(std::make_pair(tmpID,
[=](ejson::Object& _data) {
JUS_ERROR(" ==> group get return ...");
if (_data["return"].isArray() == false) {
returnBool(transactionId, false);
} else {
m_clientgroups = convertJsonTo<std::vector<std::string>>(_data["return"]);
returnBool(transactionId, true);
}
}));
}
if (m_userService != nullptr) {
m_userService->SendData(m_uid2, gwCall);
} else {
protocolError("gateWay internal error 3");
}
} else {
returnBool(transactionId, false);
}
}));
}
if (m_userService != nullptr) {
m_userService->SendData(-m_uid, gwCall);
m_userService->SendData(m_uid2, gwCall);
} else {
protocolError("gateWay internal error 3");
}
@ -218,6 +249,8 @@ void jus::GateWayClient::onClientData(std::string _value) {
ejson::Object linkService;
linkService.add("event", ejson::String("new"));
linkService.add("user", ejson::String(m_userConnectionName));
linkService.add("client", ejson::String(m_clientName));
linkService.add("groups", convertToJson(m_clientgroups));
srv->SendData(m_uid, linkService);
m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true));

View File

@ -34,7 +34,8 @@ namespace jus {
esignal::Signal<bool> signalIsConnected;
ememory::SharedPtr<jus::GateWayService> m_userService;
std::vector<ememory::SharedPtr<jus::GateWayService>> m_listConnectedService;
size_t m_uid;
uint64_t m_uid;
uint64_t m_uid2;
std::string m_userConnectionName;
std::string m_clientName;
std::vector<std::string> m_clientgroups;
@ -44,12 +45,13 @@ namespace jus {
public:
GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayInterface);
virtual ~GateWayClient();
void start(size_t _uid);
void start(uint64_t _uid, uint64_t _uid2);
void stop();
void onClientData(std::string _value);
void returnMessage(ejson::Object _data);
size_t getId() const {
return m_uid;
bool checkId(uint64_t _id) const {
return m_uid == _id
|| m_uid2 == _id;
}
bool isAlive();
};

View File

@ -84,11 +84,11 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
// Gateway just aswer a keep alive information ...
// Nothing to do ...
} else if (event == "new") {
int64_t clientId = etk::string_to_int64_t(_obj["client-id"].toString().get());
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
std::string userName = _obj["user"].toString().get();
clientConnect(clientId, userName);
} else if (event == "delete") {
int64_t clientId = etk::string_to_int64_t(_obj["client-id"].toString().get());
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
clientDisconnect(clientId);
} else {
JUS_ERROR("Unknow event: '" << event << "'");
@ -96,7 +96,7 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
return ejson::Null();
}
if (_obj.valueExist("call") == true) {
int64_t clientId = etk::string_to_int64_t(_obj["client-id"].toString().get());
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
ejson::Object tmpp = callJson2(clientId, _obj);
tmpp.add("client-id", ejson::String(etk::to_string(clientId)));
return tmpp;

View File

@ -79,7 +79,7 @@ namespace jus {
private:
JUS_USER_ACCESS& m_getUserInterface;
// no need of shared_ptr or unique_ptr (if service die all is lost and is client die, the gateway notify us...)
std::map<int64_t, std::pair<ememory::SharedPtr<ClientProperty>, ememory::SharedPtr<JUS_TYPE_SERVICE>>> m_interface;
std::map<uint64_t, std::pair<ememory::SharedPtr<ClientProperty>, ememory::SharedPtr<JUS_TYPE_SERVICE>>> m_interface;
public:
template<class JUS_RETURN_VALUE,
@ -104,14 +104,14 @@ namespace jus {
m_getUserInterface(_interface) {
}
void clientConnect(size_t _clientSessionID, const std::string& _userName) {
void clientConnect(uint64_t _clientSessionID, const std::string& _userName) {
std::unique_lock<std::mutex> lock(m_mutex);
JUS_DEBUG("connect : " << _clientSessionID << " to '" << _userName << "'");
ememory::SharedPtr<ClientProperty> tmpProperty = std::make_shared<ClientProperty>();
ememory::SharedPtr<JUS_TYPE_SERVICE> tmpSrv = std::make_shared<JUS_TYPE_SERVICE>(m_getUserInterface.getUser(_userName), tmpProperty);
m_interface.insert(std::make_pair(_clientSessionID, std::make_pair(tmpProperty, tmpSrv)));
}
void clientDisconnect(size_t _clientSessionID) {
void clientDisconnect(uint64_t _clientSessionID) {
std::unique_lock<std::mutex> lock(m_mutex);
JUS_DEBUG("disconnect: " << _clientSessionID);
auto it = m_interface.find(_clientSessionID);
@ -122,7 +122,7 @@ namespace jus {
}
m_interface.erase(it);
}
void clientSetName(size_t _clientSessionID, const std::string& _clientName) {
void clientSetName(uint64_t _clientSessionID, const std::string& _clientName) {
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_interface.find(_clientSessionID);
if (it == m_interface.end()) {
@ -131,7 +131,7 @@ namespace jus {
}
it->second.first->setName(_clientName);
}
void clientSetGroup(size_t _clientSessionID, const std::vector<std::string>& _clientGroups) {
void clientSetGroup(uint64_t _clientSessionID, const std::vector<std::string>& _clientGroups) {
std::unique_lock<std::mutex> lock(m_mutex);
auto it = m_interface.find(_clientSessionID);
if (it == m_interface.end()) {
@ -140,7 +140,7 @@ namespace jus {
}
it->second.first->setGroups(_clientGroups);
}
ejson::Object callJson2(size_t _clientSessionID, const ejson::Object& _obj) {
ejson::Object callJson2(uint64_t _clientSessionID, const ejson::Object& _obj) {
ejson::Object out;
auto it = m_interface.find(_clientSessionID);
if (it == m_interface.end()) {

View File

@ -24,8 +24,8 @@ bool jus::ServiceRemote::exist() {
return m_isLinked;
}
ejson::Object jus::ServiceRemote::createBaseCall(const std::string& _functionName) {
return m_clientInterface->createBaseCall(_functionName, m_name);
uint64_t jus::ServiceRemote::getId() {
return m_clientInterface->getId();
}
ejson::Object jus::ServiceRemote::callJson(const ejson::Object& _obj) {

View File

@ -9,6 +9,7 @@
#include <eproperty/Value.h>
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/AbstractFunction.h>
#include <jus/ServiceRemote.h>
namespace jus {
@ -24,105 +25,11 @@ namespace jus {
bool exist();
private:
ejson::Object callJson(const ejson::Object& _obj);
ejson::Object createBaseCall(const std::string& _functionName);
void createParam(ejson::Object& _obj) {
// Finish recursive parse ...
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const char* _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
if (_param == nullptr) {
array.add(ejson::String());
} else {
array.add(ejson::String(_param));
}
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::string& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::String(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const bool& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Boolean(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const int32_t& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const double& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const float& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
array.add(ejson::Number(_param));
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<std::string>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::String(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<bool>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (const auto& it : _param) {
array2.add(ejson::Boolean(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<int32_t>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<double>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createParam(ejson::Object& _obj, const std::vector<float>& _param, _ARGS&&... _args) {
ejson::Array array = _obj["param"].toArray();
ejson::Array array2;
for (auto& it : _param) {
array2.add(ejson::Number(it));
}
array.add(array2);
createParam(_obj, std::forward<_ARGS>(_args)...);
}
uint64_t getId();
public:
template<class... _ARGS>
void call(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -130,8 +37,7 @@ namespace jus {
}
template<class... _ARGS>
int32_t call_i(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -149,8 +55,7 @@ namespace jus {
}
template<class... _ARGS>
double call_d(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -168,8 +73,7 @@ namespace jus {
}
template<class... _ARGS>
std::string call_s(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -187,8 +91,7 @@ namespace jus {
}
template<class... _ARGS>
bool call_b(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -206,8 +109,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<int32_t> call_vi(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -237,8 +139,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<double> call_vd(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -268,8 +169,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<std::string> call_vs(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);
@ -299,8 +199,7 @@ namespace jus {
}
template<class... _ARGS>
std::vector<bool> call_vb(const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName);
createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object callElem = jus::createCallService(getId(), m_name, _functionName, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) {
JUS_WARNING("call error: " << obj["error"]);

View File

@ -36,7 +36,10 @@ int main(int _argc, const char *_argv[]) {
client1.connect("test1#atria-soft.com");
// Connect that is not us
//client1.identify("clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
bool retIdentify = client1.call_b("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
jus::Future<bool> retIdentify = client1.callAsync<bool>("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
retIdentify.wait();
//bool retIdentify = client1.call_b("identify", "clientTest1#atria-soft.com", "QSDQSDGQSF54HSXWVCSQDJ654URTDJ654NBXCDFDGAEZ51968");
// Connect to ourself:
//client1.authentificate("coucou");
//bool retAuthentify = client1.call_b("authentify", "coucou");

View File

@ -38,6 +38,9 @@ namespace appl {
}
APPL_WARNING("delete USER [STOP]");
}
const std::string& getName() {
return m_userName;
}
std::vector<std::string> getGroups(const std::string& _clientName) {
std::unique_lock<std::mutex> lock(m_mutex);
std::vector<std::string> out;
@ -119,7 +122,7 @@ namespace appl {
APPL_WARNING("delete SystemService ...");
}
public:
std::vector<std::string> getClientGroups() {
std::vector<std::string> getGroups(std::string _clientName) {
std::vector<std::string> out;
if (m_client == nullptr) {
return out;
@ -134,8 +137,15 @@ namespace appl {
}
return out;
}
std::vector<std::string> getClientServices() {
return std::vector<std::string>();
std::vector<std::string> getServices(std::string _clientName) {
std::vector<std::string> out;
if (m_user == nullptr) {
return out;
}
if (_clientName == m_user->getName()) {
out.push_back(SERVICE_NAME);
}
return out;
}
bool checkTocken(std::string _clientName, std::string _tocken) {
return m_user->checkTocken(_clientName, _tocken);
@ -151,10 +161,11 @@ int main(int _argc, const char *_argv[]) {
serviceInterface.setDescription("user interface management");
serviceInterface.setVersion("0.1.0");
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
serviceInterface.advertise("getClientGroups", &appl::SystemService::getClientGroups);
serviceInterface.advertise("getGroups", &appl::SystemService::getGroups);
serviceInterface.setLastFuncDesc("Get list of group availlable for a client name");
serviceInterface.addLastFuncParam("clientName", "Name of the client");
serviceInterface.advertise("checkTocken", &appl::SystemService::checkTocken);
serviceInterface.advertise("checkTocken", &appl::SystemService::getServices);
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if (etk::start_with(data, "--ip=") == true) {