[DEV] try to re-send async datas...
This commit is contained in:
parent
5334df4513
commit
e0861c66ac
@ -107,6 +107,15 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template<> ejson::Value convertToJson<jus::FileServer>(const jus::FileServer& _value) {
|
||||
ejson::Array out;
|
||||
/*
|
||||
for (auto &it : _value) {
|
||||
out.add(ejson::String(it));
|
||||
}
|
||||
*/
|
||||
return out;
|
||||
}
|
||||
|
||||
template<> bool convertStringTo<bool>(const std::string& _value) {
|
||||
return etk::string_to_bool(_value);
|
||||
@ -149,6 +158,9 @@ namespace jus {
|
||||
JUS_TODO("Convert string to vs");
|
||||
return out;
|
||||
}
|
||||
template<> jus::FileServer convertStringTo<jus::FileServer>(const std::string& _value) {
|
||||
return jus::FileServer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <ejson/ejson.h>
|
||||
#include <jus/debug.h>
|
||||
#include <jus/ParamType.h>
|
||||
#include <jus/File.h>
|
||||
namespace jus {
|
||||
class AbstractFunction {
|
||||
public:
|
||||
@ -55,7 +56,7 @@ namespace jus {
|
||||
virtual std::string getPrototype() const = 0;
|
||||
virtual std::string getPrototypeReturn() const = 0;
|
||||
virtual std::vector<std::string> getPrototypeParam() const = 0;
|
||||
virtual ejson::Value executeJson(const ejson::Array& _params, void* _class=nullptr) = 0;
|
||||
virtual void executeJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient, uint64_t _transactionId, uint64_t _clientId, const ejson::Array& _params, void* _class=nullptr) = 0;
|
||||
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
|
||||
};
|
||||
|
||||
|
@ -12,23 +12,63 @@
|
||||
#include <jus/AbstractFunction.h>
|
||||
namespace jus {
|
||||
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
|
||||
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
|
||||
void executeClassCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
return convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
ejson::Value ret = convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
return convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
ejson::Value ret = convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
return;
|
||||
#endif
|
||||
return ejson::Null();
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("return", ret);
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
|
||||
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
|
||||
void executeClassCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
jus::FileServer (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
jus::FileServer tmpElem = (*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
jus::FileServer tmpElem = (*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
jus::FileServer tmpElem;
|
||||
return;
|
||||
#endif
|
||||
JUS_ERROR("Must be implemented in a worker ...");
|
||||
}
|
||||
|
||||
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
|
||||
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
|
||||
void executeClassCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
@ -40,12 +80,21 @@ namespace jus {
|
||||
(*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
return;
|
||||
#endif
|
||||
return ejson::Null();
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("return", ejson::Null());
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
|
||||
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
|
||||
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
|
||||
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer,
|
||||
JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const std::vector<std::string>& _params) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
@ -60,7 +109,9 @@ namespace jus {
|
||||
return "";
|
||||
}
|
||||
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
|
||||
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
|
||||
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer,
|
||||
void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const std::vector<std::string>& _params) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
@ -113,37 +164,49 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
|
||||
void executeJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
const ejson::Array& _params,
|
||||
void* _class) override {
|
||||
JUS_CLASS_TYPE* tmpClass = nullptr;
|
||||
if (_class != nullptr) {
|
||||
tmpClass = (JUS_CLASS_TYPE*)_class;
|
||||
}
|
||||
ejson::Object out;
|
||||
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
JUS_ERROR("Wrong number of Parameters ...");
|
||||
out.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
|
||||
std::string help = "request ";
|
||||
help += etk::to_string(_params.size());
|
||||
help += " parameters and need ";
|
||||
help += etk::to_string(sizeof...(JUS_TYPES));
|
||||
help += " parameters. prototype function:";
|
||||
help += getPrototype();
|
||||
out.add("error-help", ejson::String(help));
|
||||
return out;
|
||||
answer.add("error-help", ejson::String(help));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
|
||||
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
|
||||
return out;
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
|
||||
answer.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
ejson::Value retVal = jus::executeClassCallJson(tmpClass, m_function, _params);
|
||||
out.add("return", retVal);
|
||||
return out;
|
||||
jus::executeClassCallJson(_interfaceClient, _transactionId, _clientId, tmpClass, m_function, _params);
|
||||
}
|
||||
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
|
||||
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
|
||||
|
@ -12,23 +12,37 @@
|
||||
#include <jus/AbstractFunction.h>
|
||||
namespace jus {
|
||||
template <class JUS_RETURN, class... JUS_TYPES>
|
||||
ejson::Value executeCallJson(JUS_RETURN (*_func)(JUS_TYPES...), const ejson::Array& _params) {
|
||||
void executeCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_RETURN (*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
return convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
ejson::Value ret = convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
return convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
ejson::Value ret = convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
#endif
|
||||
return ejson::Null();
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("return", ret);
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
|
||||
template <class... JUS_TYPES>
|
||||
ejson::Value executeCallJson(void (*_func)(JUS_TYPES...), const ejson::Array& _params) {
|
||||
void executeCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
void (*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
@ -41,7 +55,16 @@ namespace jus {
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
return ejson::Null();
|
||||
_interfaceClient->addAsync([=](TcpString* _interface) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("return", ejson::Null());
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interface->write(answer.generateMachineString());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <class JUS_RETURN, class... JUS_TYPES>
|
||||
@ -113,33 +136,43 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
|
||||
ejson::Object out;
|
||||
void executeJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
const ejson::Array& _params,
|
||||
void* _class) override {
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
JUS_ERROR("Wrong number of Parameters ...");
|
||||
out.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
|
||||
std::string help = "request ";
|
||||
help += etk::to_string(_params.size());
|
||||
help += " parameters and need ";
|
||||
help += etk::to_string(sizeof...(JUS_TYPES));
|
||||
help += " parameters. prototype function:";
|
||||
help += getPrototype();
|
||||
out.add("error-help", ejson::String(help));
|
||||
return out;
|
||||
answer.add("error-help", ejson::String(help));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
|
||||
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
|
||||
return out;
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
|
||||
answer.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
ejson::Value retVal = jus::executeCallJson(m_function, _params);
|
||||
out.add("return", retVal);
|
||||
return out;
|
||||
jus::executeCallJson(_interfaceClient, _transactionId, _clientId, m_function, _params);
|
||||
}
|
||||
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
|
||||
std::string out;
|
||||
|
38
jus/File.cpp
Normal file
38
jus/File.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#include <jus/File.h>
|
||||
#include <etk/types.h>
|
||||
#include <etk/stdTools.h>
|
||||
|
||||
|
||||
|
||||
jus::File::File() {
|
||||
|
||||
}
|
||||
|
||||
jus::File::File(const std::string& _filename) {
|
||||
|
||||
}
|
||||
|
||||
jus::File::File(const std::string& _mineType, std::vector<uint8_t> _data) {
|
||||
|
||||
}
|
||||
jus::FileServer::FileServer() {
|
||||
|
||||
}
|
||||
jus::FileServer::FileServer(const std::string& _filename) {
|
||||
m_name = _filename;
|
||||
}
|
||||
|
||||
|
||||
namespace etk {
|
||||
template<>
|
||||
std::string to_string<jus::FileServer>(jus::FileServer const& _obj) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
33
jus/File.h
Normal file
33
jus/File.h
Normal file
@ -0,0 +1,33 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2016, Edouard DUPIN, all right reserved
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
#include <etk/types.h>
|
||||
|
||||
namespace jus {
|
||||
class File {
|
||||
private:
|
||||
std::string m_mineType;
|
||||
std::vector<uint8_t> m_data;
|
||||
public:
|
||||
File();
|
||||
File(const std::string& _filename);
|
||||
File(const std::string& _mineType, std::vector<uint8_t> _data);
|
||||
const std::string& getMineType() {
|
||||
return m_mineType;
|
||||
}
|
||||
const std::vector<uint8_t>& getData() {
|
||||
return m_data;
|
||||
}
|
||||
};
|
||||
class FileServer {
|
||||
private:
|
||||
std::string m_name;
|
||||
public:
|
||||
FileServer();
|
||||
FileServer(const std::string& _filename);
|
||||
};
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <jus/Future.h>
|
||||
#include <jus/debug.h>
|
||||
#include <unistd.h>
|
||||
#include <jus/File.h>
|
||||
|
||||
namespace jus {
|
||||
template<>
|
||||
@ -488,6 +489,33 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template<>
|
||||
jus::File jus::Future<jus::File>::get() {
|
||||
jus::File out;
|
||||
if (m_data == nullptr) {
|
||||
return out;
|
||||
}
|
||||
// TODO :...
|
||||
/*
|
||||
ejson::Value val = m_data->m_returnData["return"];
|
||||
if (val.exist() == false) {
|
||||
JUS_WARNING("No Return value ...");
|
||||
return out;
|
||||
}
|
||||
if (val.isArray() == false) {
|
||||
JUS_WARNING("Wrong return Type get '" << val.getType() << " instead of 'Array'");
|
||||
return out;
|
||||
}
|
||||
for (auto it : val.toArray()) {
|
||||
if (it.isBoolean() == false) {
|
||||
JUS_WARNING("Wrong return Type (part of array) get '" << it.getType() << " instead of 'Boolean'");
|
||||
continue;
|
||||
}
|
||||
out.push_back(it.toBoolean().get());
|
||||
}
|
||||
*/
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,7 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, jus::FutureData::ObserverFi
|
||||
m_data->m_sendTime = std::chrono::steady_clock::now();
|
||||
m_data->m_transactionId = _transactionId;
|
||||
m_data->m_isFinished = false;
|
||||
m_data->m_isSynchronous = false;
|
||||
m_data->m_callbackFinish = _callback;
|
||||
}
|
||||
|
||||
@ -42,6 +43,7 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Ob
|
||||
m_data->m_sendTime = std::chrono::steady_clock::now();
|
||||
m_data->m_transactionId = _transactionId;
|
||||
m_data->m_isFinished = _isFinished;
|
||||
m_data->m_isSynchronous = false;
|
||||
m_data->m_returnData = _returnData;
|
||||
m_data->m_callbackFinish = _callback;
|
||||
if (m_data->m_isFinished == true) {
|
||||
@ -67,17 +69,50 @@ jus::FutureBase jus::FutureBase::operator= (const jus::FutureBase& _base) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
void jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
|
||||
bool jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
|
||||
if (m_data == nullptr) {
|
||||
JUS_ERROR(" Not a valid future ...");
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
m_data->m_receiveTime = std::chrono::steady_clock::now();
|
||||
if (m_data->m_isSynchronous == true) {
|
||||
m_data->m_returnData = _returnValue;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_returnValue.valueExist("part") == true) {
|
||||
uint64_t idPart = _returnValue["part"].toNumber().getU64();
|
||||
if (idPart == 0) {
|
||||
m_data->m_returnData = _returnValue;
|
||||
} else {
|
||||
m_data->m_returnDataPart.push_back(_returnValue["data"]);
|
||||
}
|
||||
if (_returnValue.valueExist("finish") == true) {
|
||||
if (_returnValue["finish"].toBoolean().get() == true) {
|
||||
m_data->m_isFinished = true;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// finish is false ==> normal case ...
|
||||
}
|
||||
return false;
|
||||
}
|
||||
m_data->m_returnData = _returnValue;
|
||||
m_data->m_isFinished = true;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
m_data->m_callbackFinish(*this);
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void jus::FutureBase::setSynchronous() {
|
||||
if (m_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_data->m_isSynchronous = true;
|
||||
}
|
||||
|
||||
uint64_t jus::FutureBase::getTransactionId() {
|
||||
|
@ -17,7 +17,8 @@ namespace jus {
|
||||
FutureBase(uint64_t _transactionId, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Object _returnData, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
jus::FutureBase operator= (const jus::FutureBase& _base);
|
||||
void setAnswer(const ejson::Object& _returnValue);
|
||||
bool setAnswer(const ejson::Object& _returnValue);
|
||||
void setSynchronous();
|
||||
uint64_t getTransactionId();
|
||||
bool hasError();
|
||||
std::string getErrorType();
|
||||
|
@ -12,11 +12,13 @@ namespace jus {
|
||||
class FutureBase;
|
||||
class FutureData {
|
||||
public:
|
||||
using ObserverFinish = std::function<void(jus::FutureBase)>; //!< Define an Observer: function pointer
|
||||
using ObserverFinish = std::function<bool(jus::FutureBase)>; //!< Define an Observer: function pointer
|
||||
public:
|
||||
uint64_t m_transactionId;
|
||||
bool m_isSynchronous;
|
||||
bool m_isFinished;
|
||||
ejson::Object m_returnData;
|
||||
std::vector<ejson::Value> m_returnDataPart;
|
||||
ObserverFinish m_callbackFinish;
|
||||
std::chrono::steady_clock::time_point m_sendTime;
|
||||
std::chrono::steady_clock::time_point m_receiveTime;
|
||||
|
@ -362,6 +362,14 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
tmpp["id"].toNumber().set(data["id"].toNumber().getU64());
|
||||
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
|
||||
m_interfaceClient.write(tmpp.generateMachineString());
|
||||
if (tmpp.valueExist("part") == true) {
|
||||
// multiple send element ...
|
||||
if (tmpp.valueExist("finish") == true) {
|
||||
return tmpp["finish"].toBoolean().get();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -371,7 +379,9 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, const std::string& _functionName, ejson::Array _params, jus::FutureData::ObserverFinish _callback) {
|
||||
uint64_t id = getId();
|
||||
ejson::Object callElem = jus::createCallJson(id, _functionName, _params);
|
||||
return callJson(_callerId, _srv, id, callElem, _callback);
|
||||
jus::FutureBase ret = callJson(_callerId, _srv, id, callElem, _callback);
|
||||
ret.setSynchronous();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t jus::GateWayClient::getId() {
|
||||
@ -400,24 +410,24 @@ jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId, ememory::Shared
|
||||
|
||||
void jus::GateWayClient::returnMessage(ejson::Object _data) {
|
||||
jus::FutureBase future;
|
||||
{
|
||||
uint64_t tid = _data["id"].toNumber().get();
|
||||
if (tid == 0) {
|
||||
if (_data["error"].toString().get() == "PROTOCOL-ERROR") {
|
||||
JUS_ERROR("Get a Protocol error ...");
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto &it : m_pendingCall) {
|
||||
if (it.isValid() == false) {
|
||||
continue;
|
||||
}
|
||||
it.setAnswer(_data);
|
||||
uint64_t tid = _data["id"].toNumber().get();
|
||||
if (tid == 0) {
|
||||
if (_data["error"].toString().get() == "PROTOCOL-ERROR") {
|
||||
JUS_ERROR("Get a Protocol error ...");
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto &it : m_pendingCall) {
|
||||
if (it.isValid() == false) {
|
||||
continue;
|
||||
}
|
||||
m_pendingCall.clear();
|
||||
} else {
|
||||
JUS_ERROR("call with no ID ==> error ...");
|
||||
it.setAnswer(_data);
|
||||
}
|
||||
return;
|
||||
m_pendingCall.clear();
|
||||
} else {
|
||||
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()) {
|
||||
@ -429,8 +439,8 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// TODO : Do it better ...
|
||||
future = *it;
|
||||
it = m_pendingCall.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -438,6 +448,22 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
|
||||
JUS_WARNING("Action to do ...");
|
||||
return;
|
||||
}
|
||||
future.setAnswer(_data);
|
||||
bool ret = future.setAnswer(_data);
|
||||
if (ret == true) {
|
||||
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;
|
||||
}
|
||||
it = m_pendingCall.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <jus/ParamType.h>
|
||||
#include <jus/debug.h>
|
||||
#include <jus/File.h>
|
||||
|
||||
|
||||
jus::ParamType::ParamType(const char* _name):
|
||||
@ -55,4 +56,10 @@ generate_basic_type(std::vector<uint64_t>, "vector:uint64");
|
||||
generate_basic_type(std::vector<uint32_t>, "vector:uint32");
|
||||
generate_basic_type(std::vector<uint16_t>, "vector:uint16");
|
||||
generate_basic_type(std::vector<uint8_t>, "vector:uint8");
|
||||
generate_basic_type(std::vector<std::string>, "vector:string");
|
||||
generate_basic_type(std::vector<std::string>, "vector:string");
|
||||
|
||||
|
||||
generate_basic_type(jus::File, "file");
|
||||
generate_basic_type(jus::FileServer, "file");
|
||||
|
||||
|
||||
|
@ -15,7 +15,8 @@
|
||||
jus::Service::Service() :
|
||||
propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Service::onPropertyChangeIp),
|
||||
propertyPort(this, "port", 1982, "Port to connect server", &jus::Service::onPropertyChangePort) {
|
||||
m_interfaceClient.connect(this, &jus::Service::onClientData);
|
||||
m_interfaceClient = std::make_shared<jus::TcpString>();
|
||||
m_interfaceClient->connect(this, &jus::Service::onClientData);
|
||||
|
||||
advertise("getExtention", &jus::Service::getExtention);
|
||||
setLastFuncDesc("Get List of availlable extention of this service");
|
||||
@ -35,16 +36,18 @@ std::vector<std::string> jus::Service::getExtention() {
|
||||
|
||||
void jus::Service::onClientData(std::string _value) {
|
||||
ejson::Object request(_value);
|
||||
ejson::Value tmpID = request["id"];
|
||||
request.remove("id");
|
||||
uint64_t tmpID = request["id"].toNumber().getU64();
|
||||
//request.remove("id");
|
||||
JUS_INFO("Request: " << _value);
|
||||
ejson::Value answer = callJson(request);
|
||||
callJson(tmpID, request);
|
||||
/*
|
||||
// check if an answer is needed
|
||||
if (answer.isNull() == false) {
|
||||
answer.toObject().add("id", tmpID);
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void jus::Service::onPropertyChangeIp() {
|
||||
@ -64,29 +67,29 @@ void jus::Service::connect(const std::string& _serviceName, uint32_t _numberRetr
|
||||
JUS_DEBUG("connect [STOP] ==> can not connect");
|
||||
return;
|
||||
}
|
||||
m_interfaceClient.setInterface(std::move(connection));
|
||||
m_interfaceClient.connect();
|
||||
m_interfaceClient.write(std::string("{\"connect-service\":\"") + _serviceName + "\"}");
|
||||
m_interfaceClient->setInterface(std::move(connection));
|
||||
m_interfaceClient->connect();
|
||||
m_interfaceClient->write(std::string("{\"connect-service\":\"") + _serviceName + "\"}");
|
||||
JUS_DEBUG("connect [STOP]");
|
||||
}
|
||||
|
||||
void jus::Service::disconnect(){
|
||||
JUS_DEBUG("disconnect [START]");
|
||||
m_interfaceClient.disconnect();
|
||||
m_interfaceClient->disconnect();
|
||||
JUS_DEBUG("disconnect [STOP]");
|
||||
}
|
||||
|
||||
bool jus::Service::GateWayAlive() {
|
||||
return m_interfaceClient.isActive();
|
||||
return m_interfaceClient->isActive();
|
||||
}
|
||||
|
||||
void jus::Service::pingIsAlive() {
|
||||
if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(30)) {
|
||||
m_interfaceClient.write("{\"event\":\"IS-ALIVE\"}");
|
||||
if (std::chrono::steady_clock::now() - m_interfaceClient->getLastTimeSend() >= std::chrono::seconds(30)) {
|
||||
m_interfaceClient->write("{\"event\":\"IS-ALIVE\"}");
|
||||
}
|
||||
}
|
||||
|
||||
ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
|
||||
void jus::Service::callJson(uint64_t _transactionId, const ejson::Object& _obj) {
|
||||
if (_obj.valueExist("event") == true) {
|
||||
std::string event = _obj["event"].toString().get();
|
||||
if (event == "IS-ALIVE") {
|
||||
@ -104,22 +107,27 @@ ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
|
||||
} else {
|
||||
JUS_ERROR("Unknow event: '" << event << "'");
|
||||
}
|
||||
return ejson::Null();
|
||||
return;
|
||||
}
|
||||
ejson::Object tmpp;
|
||||
ejson::Object answer;
|
||||
uint64_t clientId = _obj["client-id"].toNumber().getU64();
|
||||
if (_obj.valueExist("call") == true) {
|
||||
std::string call = _obj["call"].toString().get();
|
||||
if (isFunctionAuthorized(clientId, call) == true) {
|
||||
tmpp = callJson2(clientId, _obj);
|
||||
tmpp.add("client-id", ejson::Number(clientId));
|
||||
return tmpp;
|
||||
callJson2(_transactionId, clientId, call, _obj["param"].toArray());
|
||||
return;
|
||||
} else {
|
||||
tmpp.add("error", ejson::String("NOT-AUTHORIZED-FUNCTION"));
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(clientId));
|
||||
answer.add("error", ejson::String("NOT-AUTHORIZED-FUNCTION"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
tmpp.add("error", ejson::String("NOT-IMPLEMENTED-FUNCTION"));
|
||||
}
|
||||
tmpp.add("client-id", ejson::Number(clientId));
|
||||
return tmpp;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(clientId));
|
||||
answer.add("error", ejson::String("NOT-IMPLEMENTED-FUNCTION"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ namespace jus {
|
||||
public:
|
||||
eproperty::Value<std::string> propertyIp;
|
||||
eproperty::Value<uint16_t> propertyPort;
|
||||
private:
|
||||
jus::TcpString m_interfaceClient;
|
||||
protected:
|
||||
ememory::SharedPtr<jus::TcpString> m_interfaceClient;
|
||||
uint32_t m_id;
|
||||
std::vector<std::string> m_newData;
|
||||
public:
|
||||
@ -77,15 +77,15 @@ namespace jus {
|
||||
void onPropertyChangePort();
|
||||
/**
|
||||
* @brief A extern client connect on specific user
|
||||
* @param[in] _clientSessionID Source session Id on the client
|
||||
* @param[in] _clientId Source session Id on the client
|
||||
* @param[in] _userName User name of the client to connect
|
||||
* @todo Set a relur like ==> service not availlable / service close / service maintenance / service right reject
|
||||
*/
|
||||
virtual void clientConnect(size_t _clientSessionID, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) = 0;
|
||||
virtual void clientDisconnect(size_t _clientSessionID) = 0;
|
||||
virtual void clientConnect(uint64_t _clientId, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) = 0;
|
||||
virtual void clientDisconnect(uint64_t _clientId) = 0;
|
||||
// Genenric function call:
|
||||
ejson::Value callJson(const ejson::Object& _obj);
|
||||
virtual ejson::Object callJson2(size_t _clientId, const ejson::Object& _obj) = 0;
|
||||
void callJson(uint64_t _transactionId, const ejson::Object& _obj);
|
||||
virtual void callJson2(uint64_t _transactionId, uint64_t _clientId, const std::string& _call, const ejson::Array& _obj) = 0;
|
||||
std::vector<std::string> getExtention();
|
||||
public:
|
||||
// Add Local fuction (depend on this class)
|
||||
@ -154,21 +154,21 @@ namespace jus {
|
||||
m_getUserInterface(_interface) {
|
||||
|
||||
}
|
||||
bool isFunctionAuthorized(uint64_t _clientSessionID, const std::string& _funcName) {
|
||||
auto it = m_interface.find(_clientSessionID);
|
||||
bool isFunctionAuthorized(uint64_t _clientId, const std::string& _funcName) {
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
return false;
|
||||
}
|
||||
return it->second.first->isFunctionAuthorized(_funcName);
|
||||
}
|
||||
void clientConnect(uint64_t _clientSessionID, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) {
|
||||
void clientConnect(uint64_t _clientId, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
JUS_DEBUG("connect: " << _clientSessionID << " to '" << _userName << "'");
|
||||
JUS_DEBUG("connect: " << _clientId << " to '" << _userName << "'");
|
||||
JUS_DEBUG(" client name='" << _clientName << "'");
|
||||
JUS_DEBUG(" groups=" << etk::to_string(_groups));
|
||||
ememory::SharedPtr<ClientProperty> tmpProperty = std::make_shared<ClientProperty>(_clientName, _groups);
|
||||
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)));
|
||||
m_interface.insert(std::make_pair(_clientId, std::make_pair(tmpProperty, tmpSrv)));
|
||||
// enable list of function availlable:
|
||||
for (auto &it : m_listFunction) {
|
||||
if (it == nullptr) {
|
||||
@ -177,72 +177,85 @@ namespace jus {
|
||||
tmpProperty->addAuthorized(it->getName());
|
||||
}
|
||||
}
|
||||
void clientDisconnect(uint64_t _clientSessionID) {
|
||||
void clientDisconnect(uint64_t _clientId) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
JUS_DEBUG("disconnect: " << _clientSessionID);
|
||||
auto it = m_interface.find(_clientSessionID);
|
||||
JUS_DEBUG("disconnect: " << _clientId);
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
JUS_WARNING("disconnect ==> Not find Client ID " << _clientSessionID);
|
||||
JUS_WARNING("disconnect ==> Not find Client ID " << _clientId);
|
||||
// noting to do ==> user never conected.
|
||||
return;
|
||||
}
|
||||
m_interface.erase(it);
|
||||
}
|
||||
void clientSetName(uint64_t _clientSessionID, const std::string& _clientName) {
|
||||
void clientSetName(uint64_t _clientId, const std::string& _clientName) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
auto it = m_interface.find(_clientSessionID);
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
JUS_ERROR("Change the client property but client was not created ...");
|
||||
return;
|
||||
}
|
||||
it->second.first->setName(_clientName);
|
||||
}
|
||||
void clientSetGroup(uint64_t _clientSessionID, const std::vector<std::string>& _clientGroups) {
|
||||
void clientSetGroup(uint64_t _clientId, const std::vector<std::string>& _clientGroups) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
auto it = m_interface.find(_clientSessionID);
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
JUS_ERROR("Change the client property but client was not created ...");
|
||||
return;
|
||||
}
|
||||
it->second.first->setGroups(_clientGroups);
|
||||
}
|
||||
ejson::Object callJson2(uint64_t _clientSessionID, const ejson::Object& _obj) {
|
||||
ejson::Object out;
|
||||
auto it = m_interface.find(_clientSessionID);
|
||||
void callJson2(uint64_t _transactionId, uint64_t _clientId, const std::string& _call, const ejson::Array& _params) {
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
out.add("error", ejson::String("CLIENT-UNKNOW"));
|
||||
return out;
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("CLIENT-UNKNOW"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
return;
|
||||
}
|
||||
std::string call = _obj["call"].toString().get();
|
||||
const ejson::Array param = _obj["param"].toArray();
|
||||
for (auto &it2 : m_listFunction) {
|
||||
if (it2 == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it2->getName() != call) {
|
||||
if (it2->getName() != _call) {
|
||||
continue;
|
||||
}
|
||||
switch (it2->getType()) {
|
||||
case jus::AbstractFunction::type::object: {
|
||||
JUS_TYPE_SERVICE* elem = it->second.second.get();
|
||||
return it2->executeJson(param, (void*)elem).toObject();
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)elem);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::local: {
|
||||
return it2->executeJson(param, (void*)((RemoteProcessCall*)this)).toObject();
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)((RemoteProcessCall*)this));
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::service: {
|
||||
return it2->executeJson(param, (void*)this).toObject();
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)this);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::global: {
|
||||
return it2->executeJson(param, nullptr).toObject();
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, nullptr);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::unknow:
|
||||
JUS_ERROR("Can not call unknow type ...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
out.add("error", ejson::String("FUNCTION-UNKNOW"));
|
||||
return out;
|
||||
{
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("FUNCTION-UNKNOW"));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -11,15 +11,19 @@
|
||||
jus::TcpString::TcpString(enet::Tcp _connection) :
|
||||
m_connection(std::move(_connection)),
|
||||
m_thread(nullptr),
|
||||
m_obsercerElement(nullptr) {
|
||||
m_obsercerElement(nullptr),
|
||||
m_threadAsync(nullptr) {
|
||||
m_threadRunning = false;
|
||||
m_threadAsyncRunning = false;
|
||||
}
|
||||
|
||||
jus::TcpString::TcpString() :
|
||||
m_connection(),
|
||||
m_thread(nullptr),
|
||||
m_obsercerElement(nullptr) {
|
||||
m_obsercerElement(nullptr),
|
||||
m_threadAsync(nullptr) {
|
||||
m_threadRunning = false;
|
||||
m_threadAsyncRunning = false;
|
||||
}
|
||||
|
||||
void jus::TcpString::setInterface(enet::Tcp _connection) {
|
||||
@ -66,6 +70,14 @@ void jus::TcpString::connect(bool _async){
|
||||
JUS_ERROR("creating callback thread!");
|
||||
return;
|
||||
}
|
||||
m_threadAsyncRunning = true;
|
||||
m_threadAsync = new std::thread([&](void *){ this->threadAsyncCallback();}, nullptr);
|
||||
if (m_threadAsync == nullptr) {
|
||||
m_threadAsyncRunning = false;
|
||||
JUS_ERROR("creating async sender thread!");
|
||||
return;
|
||||
}
|
||||
|
||||
while ( _async == false
|
||||
&& m_threadRunning == true
|
||||
&& m_connection.getConnectionStatus() != enet::Tcp::status::link) {
|
||||
@ -81,9 +93,8 @@ void jus::TcpString::connect(bool _async){
|
||||
|
||||
void jus::TcpString::disconnect(bool _inThreadStop){
|
||||
JUS_DEBUG("disconnect [START]");
|
||||
if (m_thread != nullptr) {
|
||||
m_threadRunning = false;
|
||||
}
|
||||
m_threadRunning = false;
|
||||
m_threadAsyncRunning = false;
|
||||
if (m_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
uint32_t size = 0xFFFFFFFF;
|
||||
m_connection.write(&size, 4);
|
||||
@ -91,6 +102,11 @@ void jus::TcpString::disconnect(bool _inThreadStop){
|
||||
if (m_connection.getConnectionStatus() != enet::Tcp::status::unlink) {
|
||||
m_connection.unlink();
|
||||
}
|
||||
if (m_threadAsync != nullptr) {
|
||||
m_threadAsync->join();
|
||||
delete m_threadAsync;
|
||||
m_threadAsync = nullptr;
|
||||
}
|
||||
if (_inThreadStop == false) {
|
||||
if (m_thread != nullptr) {
|
||||
m_thread->join();
|
||||
@ -147,3 +163,36 @@ std::string jus::TcpString::read() {
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void jus::TcpString::threadAsyncCallback() {
|
||||
ethread::setName("Async-sender");
|
||||
// get datas:
|
||||
while ( m_threadAsyncRunning == true
|
||||
&& m_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
if (m_threadAsyncList.size() == 0) {
|
||||
usleep(10000);
|
||||
continue;
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(m_threadAsyncMutex);
|
||||
auto it = m_threadAsyncList.begin();
|
||||
while (it != m_threadAsyncList.end()) {
|
||||
bool ret = m_threadAsyncList(this);
|
||||
if (ret == true) {
|
||||
// Remove it ...
|
||||
it = m_threadAsyncList.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
JUS_VERBOSE("Receive data: '" << data << "'");
|
||||
if (data.size() != 0) {
|
||||
m_lastReceive = std::chrono::steady_clock::now();
|
||||
if (m_obsercerElement != nullptr) {
|
||||
m_obsercerElement(std::move(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
m_threadRunning = false;
|
||||
JUS_DEBUG("End of thread");
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,19 @@ namespace jus {
|
||||
const std::chrono::steady_clock::time_point& getLastTimeSend() {
|
||||
return m_lastSend;
|
||||
}
|
||||
private:
|
||||
using ActionAsync = std::function<bool(TcpString* _interface)>;
|
||||
std::mutex m_threadAsyncMutex;
|
||||
std::thread* m_threadAsync;
|
||||
bool m_threadAsyncRunning;
|
||||
std::vector<ActionAsync> m_threadAsyncList;
|
||||
private:
|
||||
void threadAsyncCallback();
|
||||
public:
|
||||
void addAsync(ActionAsync _elem) {
|
||||
std::unique_lock<std::mutex> lock(m_threadAsyncMutex);
|
||||
m_threadAsyncList.push_back(_elem);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ def create(target, module_name):
|
||||
'jus/AbstractFunctionTypeClass.cpp',
|
||||
'jus/FutureBase.cpp',
|
||||
'jus/Future.cpp',
|
||||
'jus/File.cpp',
|
||||
'jus/ParamType.cpp',
|
||||
'jus/Client.cpp',
|
||||
'jus/GateWay.cpp',
|
||||
@ -54,6 +55,7 @@ def create(target, module_name):
|
||||
'jus/FutureData.h',
|
||||
'jus/FutureBase.h',
|
||||
'jus/Future.h',
|
||||
'jus/File.h',
|
||||
'jus/ParamType.h',
|
||||
'jus/debug.h',
|
||||
'jus/Client.h',
|
||||
|
@ -145,6 +145,10 @@ int main(int _argc, const char *_argv[]) {
|
||||
jus::Future<uint32_t> retCount = remoteServicePicture.call("getAlbumCount", it).wait();
|
||||
if (retCount.get() != 0) {
|
||||
APPL_INFO(" - " << it << " / " << retCount.get() << " images");
|
||||
jus::Future<std::vector<std::string>> retListImage = remoteServicePicture.call("getAlbumListPicture", it).wait();
|
||||
for (auto &it3 : retListImage.get()) {
|
||||
APPL_INFO(" - " << it3);
|
||||
}
|
||||
} else {
|
||||
APPL_INFO(" - " << it);
|
||||
}
|
||||
@ -153,6 +157,14 @@ int main(int _argc, const char *_argv[]) {
|
||||
jus::Future<uint32_t> retCount2 = remoteServicePicture.call("getAlbumCount", it2).wait();
|
||||
if (retCount2.get() != 0) {
|
||||
APPL_INFO(" - " << it2 << " / " << retCount2.get() << " images");
|
||||
jus::Future<std::vector<std::string>> retListImage = remoteServicePicture.call("getAlbumListPicture", it2).wait();
|
||||
for (auto &it3 : retListImage.get()) {
|
||||
APPL_INFO(" - " << it3);
|
||||
jus::Future<jus::File> retListImage = remoteServicePicture.call("getAlbumPicture", it3).wait();
|
||||
jus::File tmpFile = retListImage.get();
|
||||
APPL_INFO(" mine-type: " << tmpFile.getMineType());
|
||||
APPL_INFO(" size: " << tmpFile.getData().size());
|
||||
}
|
||||
} else {
|
||||
APPL_INFO(" - " << it2);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <appl/debug.h>
|
||||
#include <jus/Service.h>
|
||||
#include <jus/File.h>
|
||||
#include <etk/etk.h>
|
||||
#include <unistd.h>
|
||||
#include <mutex>
|
||||
@ -19,46 +20,23 @@ namespace appl {
|
||||
std::mutex m_mutex;
|
||||
std::string m_userName;
|
||||
std::string m_basePath;
|
||||
ejson::Document m_database;
|
||||
std::map<uint64_t,std::string> m_listFile;
|
||||
public:
|
||||
User(const std::string& _userName) :
|
||||
m_userName(_userName) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
APPL_WARNING("new USER: " << m_userName);
|
||||
APPL_WARNING("new USER: " << m_userName << " [START]");
|
||||
m_basePath = std::string("USERDATA:") + m_userName + "/";
|
||||
}
|
||||
~User() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
APPL_WARNING("delete USER [START]");
|
||||
APPL_WARNING("delete USER [STOP]");
|
||||
}
|
||||
// Return the list of root albums
|
||||
std::vector<std::string> getAlbums() {
|
||||
return getSubAlbums("");
|
||||
}
|
||||
// Get the list of sub album
|
||||
std::vector<std::string> getSubAlbums(const std::string& _parrentAlbum) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::vector<std::string> out;
|
||||
etk::FSNode node(m_basePath + _parrentAlbum);
|
||||
std::vector<etk::FSNode*> tmpList = node.folderGetSubList(false, true, false, false);
|
||||
for (auto &it : tmpList) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if ( _parrentAlbum.size() == 0
|
||||
|| _parrentAlbum[_parrentAlbum.size()-1] == '/') {
|
||||
out.push_back(_parrentAlbum + it->getNameFile());
|
||||
} else {
|
||||
out.push_back(_parrentAlbum + "/" + it->getNameFile());
|
||||
}
|
||||
APPL_WARNING("new USER: " << m_userName);
|
||||
bool ret = m_database.load(m_basePath + "database.json");
|
||||
if (ret == false) {
|
||||
APPL_WARNING(" ==> LOAD error");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
uint32_t getAlbumCount(const std::string& _album) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
etk::FSNode node(m_basePath + _album);
|
||||
// Load all files (image and video ...)
|
||||
etk::FSNode node(m_basePath);
|
||||
std::vector<etk::FSNode*> tmpList = node.folderGetSubList(false, false, true, false);
|
||||
uint32_t nbElem = 0;
|
||||
APPL_WARNING("Find " << tmpList.size() << " files");
|
||||
for (auto &it : tmpList) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
@ -66,24 +44,163 @@ namespace appl {
|
||||
if ( etk::end_with(it->getNameFile(), ".svg", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".bmp", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".png", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".jpg", false) == true) {
|
||||
nbElem++;
|
||||
|| etk::end_with(it->getNameFile(), ".jpg", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".tga", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".mp4", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".avi", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".mov", false) == true
|
||||
|| etk::end_with(it->getNameFile(), ".mkv", false) == true) {
|
||||
// TODO : Do it better (proto ..)
|
||||
std::string idString = it->getNameFile();
|
||||
idString.resize(idString.size()-4);
|
||||
uint64_t id = 0;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << idString;
|
||||
ss >> id;
|
||||
if (id <= 1024) {
|
||||
APPL_WARNING(" ==> REJECTED file " << it->getNameFile() << " with ID = " << id);
|
||||
} else {
|
||||
m_listFile.insert(std::make_pair(id, it->getNameFile()));
|
||||
APPL_WARNING(" ==> load file " << it->getNameFile() << " with ID = " << id);
|
||||
}
|
||||
} else {
|
||||
APPL_WARNING(" ==> REJECT file " << it->getNameFile());
|
||||
}
|
||||
}
|
||||
return nbElem;
|
||||
APPL_WARNING("new USER: " << m_userName << " [STOP]");
|
||||
}
|
||||
// Return the list of the album files
|
||||
std::vector<std::string> getAlbumListPicture(const std::string& _album, uint32_t _startId, uint32_t _stopId) {
|
||||
~User() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
APPL_WARNING("delete USER [START]");
|
||||
APPL_DEBUG("Store User Info:");
|
||||
bool ret = m_database.storeSafe(m_basePath + "database.json");
|
||||
if (ret == false) {
|
||||
APPL_WARNING(" ==> Store error");
|
||||
}
|
||||
APPL_WARNING("delete USER [STOP]");
|
||||
}
|
||||
// Return the list of root albums
|
||||
std::vector<std::string> getAlbums() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::vector<std::string> out;
|
||||
return std::vector<std::string>();
|
||||
ejson::Array globalGroups = m_database["group-global"].toArray();
|
||||
if (globalGroups.exist() == false) {
|
||||
return out;
|
||||
}
|
||||
ejson::Object groups = m_database["groups"].toObject();
|
||||
if (groups.exist() == false) {
|
||||
return out;
|
||||
}
|
||||
for (auto it: globalGroups) {
|
||||
std::string tmpString = it.toString().get();
|
||||
if (tmpString == "") {
|
||||
continue;
|
||||
}
|
||||
out.push_back(tmpString);
|
||||
}
|
||||
return out;
|
||||
/*
|
||||
ejson::Object groups = m_database["groups"].toObject();
|
||||
if (groups.exist() == false) {
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
groups
|
||||
return getSubAlbums("");
|
||||
*/
|
||||
}
|
||||
// Get the list of sub album
|
||||
std::vector<std::string> getSubAlbums(const std::string& _album) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::vector<std::string> out;
|
||||
ejson::Object groups = m_database["groups"].toObject();
|
||||
if (groups.exist() == false) {
|
||||
return out;
|
||||
}
|
||||
// find parrentAlbum ==> to get sub group
|
||||
/*
|
||||
for (size_t iii=0; iii<groups.size(); ++iii) {
|
||||
//ejson::Object group = groups[iii].toObject()["sub"];
|
||||
if (groups.getKey(iii) != _parrentAlbum) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*/
|
||||
ejson::Object group = groups[_album].toObject();
|
||||
if (group.exist() == false) {
|
||||
return out;
|
||||
}
|
||||
ejson::Array groupSubs = group["sub"].toArray();
|
||||
for (auto it: groupSubs) {
|
||||
std::string tmpString = it.toString().get();
|
||||
if (tmpString == "") {
|
||||
continue;
|
||||
}
|
||||
out.push_back(tmpString);
|
||||
}
|
||||
// TODO: Check right
|
||||
return out;
|
||||
}
|
||||
uint32_t getAlbumCount(const std::string& _album) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
ejson::Object groups = m_database["groups"].toObject();
|
||||
if (groups.exist() == false) {
|
||||
// TODO : Throw an error ...
|
||||
return 0;
|
||||
}
|
||||
ejson::Object group = groups[_album].toObject();
|
||||
if (group.exist() == false) {
|
||||
// TODO : Throw an error ...
|
||||
return 0;
|
||||
}
|
||||
ejson::Array groupSubs = group["files"].toArray();
|
||||
// TODO: Check right
|
||||
return groupSubs.size();
|
||||
/*
|
||||
for (auto it: groupSubs) {
|
||||
uint64_t id = it.toNumber().getU64();
|
||||
if (id == 0) {
|
||||
continue;
|
||||
}
|
||||
out.push_back(id);
|
||||
}
|
||||
*/
|
||||
}
|
||||
// Return the list of the album files
|
||||
std::vector<std::string> getAlbumListPicture(const std::string& _album) {//, uint32_t _startId, uint32_t _stopId) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::vector<std::string> out;
|
||||
ejson::Object groups = m_database["groups"].toObject();
|
||||
if (groups.exist() == false) {
|
||||
// TODO : Throw an error ...
|
||||
return out;
|
||||
}
|
||||
ejson::Object group = groups[_album].toObject();
|
||||
if (group.exist() == false) {
|
||||
// TODO : Throw an error ...
|
||||
return out;
|
||||
}
|
||||
ejson::Array groupSubs = group["files"].toArray();
|
||||
|
||||
for (auto it: groupSubs) {
|
||||
uint64_t id = it.toNumber().getU64();
|
||||
/*
|
||||
auto itImage = m_listFile.find(id);
|
||||
if (itImage == m_listFile.end()) {
|
||||
|
||||
}*/
|
||||
if (id == 0) {
|
||||
continue;
|
||||
}
|
||||
out.push_back(etk::to_string(id));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
// Return a File Data (might be a picture .tiff/.png/.jpg)
|
||||
jus::FileServer getAlbumPicture(const std::string& _pictureName) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return jus::FileServer();
|
||||
}
|
||||
/*
|
||||
// Return a File Data (might be a picture .tiff/.png/.jpg)
|
||||
jus::File getAlbumPicture(const std::string& _pictureName) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return jus::File();
|
||||
}
|
||||
// Return a global UTC time
|
||||
jus::Time getAlbumPictureTime(const std::string& _pictureName) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
@ -94,6 +211,11 @@ namespace appl {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return jus::Geo();
|
||||
}
|
||||
jus::FileId addElement(const jus::File& _file) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
std::vector<std::string> out;
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
@ -148,14 +270,14 @@ namespace appl {
|
||||
return m_user->getAlbumCount(_album);
|
||||
}
|
||||
// Return the list of the album files
|
||||
std::vector<std::string> getAlbumListPicture(std::string _album, uint32_t _startId, uint32_t _stopId) {
|
||||
return m_user->getAlbumListPicture(_album, _startId, _stopId);
|
||||
std::vector<std::string> getAlbumListPicture(std::string _album) {//, uint32_t _startId, uint32_t _stopId) {
|
||||
return m_user->getAlbumListPicture(_album);//, _startId, _stopId);
|
||||
}
|
||||
/*
|
||||
// Return a File Data (might be a picture .tiff/.png/.jpg)
|
||||
jus::File getAlbumPicture(std::string _pictureName) {
|
||||
jus::FileServer getAlbumPicture(std::string _pictureName) {
|
||||
return m_user->getAlbumPicture(_pictureName);
|
||||
}
|
||||
/*
|
||||
// Return a global UTC time
|
||||
jus::Time getAlbumPictureTime(std::string _pictureName) {
|
||||
return m_user->getAlbumPictureTime(_pictureName);
|
||||
@ -209,6 +331,7 @@ int main(int _argc, const char *_argv[]) {
|
||||
serviceInterface.advertise("getSubAlbums", &appl::PictureService::getSubAlbums);
|
||||
serviceInterface.advertise("getAlbumCount", &appl::PictureService::getAlbumCount);
|
||||
serviceInterface.advertise("getAlbumListPicture", &appl::PictureService::getAlbumListPicture);
|
||||
serviceInterface.advertise("getAlbumPicture", &appl::PictureService::getAlbumPicture);
|
||||
/*
|
||||
serviceInterface.advertise("getAlbumPicture", &appl::PictureService::getAlbumPicture);
|
||||
serviceInterface.advertise("getAlbumPictureTime", &appl::PictureService::getAlbumPictureTime);
|
||||
|
Loading…
x
Reference in New Issue
Block a user