[DEV] binary transmission step 1 ==> OK
This commit is contained in:
parent
bb3858625f
commit
8aa9c0ea0d
@ -181,8 +181,7 @@ namespace jus {
|
||||
answer.add("data", ejson::String(ejson::base64::encode(&m_data.getData()[m_offset], tmpSize)));
|
||||
m_offset += tmpSize;
|
||||
m_size -= tmpSize;
|
||||
JUS_INFO("data: " << answer.generateHumanString());
|
||||
_interface->write(answer.generateMachineString());
|
||||
_interface->writeJson(answer);
|
||||
if (m_size <= 0) {
|
||||
return true;
|
||||
}
|
||||
@ -355,9 +354,11 @@ jus::AbstractFunction::AbstractFunction(const std::string& _name,
|
||||
m_description(_desc) {
|
||||
|
||||
}
|
||||
bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejson::Value& _params) {
|
||||
|
||||
|
||||
bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const std::string& _params) {
|
||||
if (createType<bool>() == _type) {
|
||||
return _params.isBoolean();
|
||||
return _params == "bool";
|
||||
}
|
||||
if ( createType<int64_t>() == _type
|
||||
|| createType<int32_t>() == _type
|
||||
@ -369,10 +370,19 @@ bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejs
|
||||
|| createType<uint8_t>() == _type
|
||||
|| createType<float>() == _type
|
||||
|| createType<double>() == _type) {
|
||||
return _params.isNumber();
|
||||
return _params == "int8"
|
||||
|| _params == "int16"
|
||||
|| _params == "int32"
|
||||
|| _params == "int64"
|
||||
|| _params == "uint8"
|
||||
|| _params == "uint16"
|
||||
|| _params == "uint32"
|
||||
|| _params == "uint64"
|
||||
|| _params == "float"
|
||||
|| _params == "double";
|
||||
}
|
||||
if (createType<std::vector<std::string>>() == _type) {
|
||||
return _params.isArray();
|
||||
return _params == "vector:string";
|
||||
}
|
||||
if ( createType<std::vector<bool>>() == _type
|
||||
|| createType<std::vector<int64_t>>() == _type
|
||||
@ -385,25 +395,30 @@ bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejs
|
||||
|| createType<std::vector<uint8_t>>() == _type
|
||||
|| createType<std::vector<float>>() == _type
|
||||
|| createType<std::vector<double>>() == _type) {
|
||||
if (_params.isObject()) {
|
||||
JUS_TODO("Special case of packaging of the data");
|
||||
return false;
|
||||
}
|
||||
return _params.isArray();
|
||||
return _params == "vector:int8"
|
||||
|| _params == "vector:int16"
|
||||
|| _params == "vector:int32"
|
||||
|| _params == "vector:int64"
|
||||
|| _params == "vector:uint8"
|
||||
|| _params == "vector:uint16"
|
||||
|| _params == "vector:uint32"
|
||||
|| _params == "vector:uint64"
|
||||
|| _params == "vector:float"
|
||||
|| _params == "vector:double"
|
||||
|| _params == "vector:empty";
|
||||
}
|
||||
if (createType<jus::File>() == _type) {
|
||||
/*
|
||||
if (_params.isObject()) {
|
||||
if (_params.toObject()["type"].toString().get() == "file") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
if (createType<std::string>() == _type) {
|
||||
return _params.isString();
|
||||
return _params == "string";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const std::string& _params) {
|
||||
return false;
|
||||
}
|
||||
|
@ -4,13 +4,22 @@
|
||||
* @license APACHE v2.0 (see license file)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <jus/TcpString.h>
|
||||
#include <eproperty/Value.h>
|
||||
#include <ejson/ejson.h>
|
||||
#include <jus/debug.h>
|
||||
#include <jus/ParamType.h>
|
||||
#include <jus/File.h>
|
||||
#include <jus/Buffer.h>
|
||||
|
||||
namespace jus {
|
||||
class TcpString;
|
||||
// define basic async call element ...
|
||||
using ActionAsyncClient = std::function<bool(TcpString* _interface, const uint32_t& _serviceId, uint64_t _transactionId, uint64_t _part)>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
namespace jus {
|
||||
class AbstractFunction {
|
||||
public:
|
||||
@ -49,19 +58,15 @@ namespace jus {
|
||||
public:
|
||||
virtual ~AbstractFunction() {};
|
||||
public:
|
||||
bool checkCompatibility(const ParamType& _type, const ejson::Value& _params);
|
||||
bool checkCompatibility(const ParamType& _type, const std::string& _params);
|
||||
public:
|
||||
std::string getPrototypeFull() const;
|
||||
virtual std::string getPrototype() const = 0;
|
||||
virtual std::string getPrototypeReturn() const = 0;
|
||||
virtual std::vector<std::string> getPrototypeParam() const = 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;
|
||||
virtual void execute(const ememory::SharedPtr<jus::TcpString>& _interfaceClient, uint64_t _transactionId, uint64_t _clientId, jus::Buffer& _params, void* _class=nullptr) = 0;
|
||||
};
|
||||
|
||||
// define basic async call element ...
|
||||
using ActionAsyncClient = std::function<bool(TcpString* _interface, const uint32_t& _serviceId, uint64_t _transactionId, uint64_t _part)>;
|
||||
|
||||
template<class JUS_TYPE>
|
||||
JUS_TYPE convertStringTo(const std::string& _value);
|
||||
@ -164,3 +169,5 @@ namespace jus {
|
||||
|
||||
}
|
||||
|
||||
#include <jus/TcpString.h>
|
||||
|
||||
|
@ -17,36 +17,35 @@
|
||||
|
||||
namespace jus {
|
||||
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_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
void executeClassCall(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
jus::Buffer& _obj) {
|
||||
std::vector<ActionAsyncClient> asyncAction;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
JUS_RETURN ret = (*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(idParam++)...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
ejson::Value ret = convertToJson(asyncAction, -1, (*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
JUS_RETURN ret = (*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(idParam--)...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
JUS_RETURN ret;
|
||||
return;
|
||||
#endif
|
||||
if (asyncAction.size() != 0) {
|
||||
JUS_ERROR("Missing send async messages");
|
||||
}
|
||||
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());
|
||||
_interfaceClient->addAsync([=](TcpString* _interface) {
|
||||
_interface->answerValue(_transactionId, ret, _clientId);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
/*
|
||||
class SendFile {
|
||||
private:
|
||||
jus::FileServer m_data;
|
||||
@ -112,20 +111,20 @@ namespace jus {
|
||||
}
|
||||
};
|
||||
template <class JUS_CLASS_TYPE, 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) {
|
||||
void executeClassCall(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
jus::FileServer (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
jus::Buffer& _obj) {
|
||||
#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++]))...);
|
||||
jus::FileServer tmpElem = (*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(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--])...);
|
||||
jus::FileServer tmpElem = (*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(idParam--)...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
jus::FileServer tmpElem;
|
||||
@ -133,70 +132,31 @@ namespace jus {
|
||||
#endif
|
||||
_interfaceClient->addAsync(SendFile(tmpElem, _transactionId, _clientId));
|
||||
}
|
||||
*/
|
||||
|
||||
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
|
||||
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;
|
||||
void executeClassCall(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_CLASS_TYPE* _pointer,
|
||||
void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...),
|
||||
jus::Buffer& _obj) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
(*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
|
||||
(*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(idParam++)...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
(*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
|
||||
(*_pointer.*_func)(_obj.getParameter<JUS_TYPES>(idParam--)...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
return;
|
||||
#endif
|
||||
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) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
return etk::to_string((*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
return etk::to_string((*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...));
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
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) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
(*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
(*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
return "";
|
||||
_interfaceClient->addAsync([=](TcpString* _interface) {
|
||||
_interface->answerVoid(_transactionId, _clientId);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
|
||||
@ -236,76 +196,43 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
void executeJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
const ejson::Array& _params,
|
||||
void* _class) override {
|
||||
void execute(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
jus::Buffer& _obj,
|
||||
void* _class) override {
|
||||
JUS_CLASS_TYPE* tmpClass = nullptr;
|
||||
if (_class != nullptr) {
|
||||
tmpClass = (JUS_CLASS_TYPE*)_class;
|
||||
}
|
||||
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
if (_obj.getNumberParameter() != sizeof...(JUS_TYPES)) {
|
||||
JUS_ERROR("Wrong number of Parameters ...");
|
||||
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 += etk::to_string(_obj.getNumberParameter());
|
||||
help += " parameters and need ";
|
||||
help += etk::to_string(sizeof...(JUS_TYPES));
|
||||
help += " parameters. prototype function:";
|
||||
help += getPrototype();
|
||||
answer.add("error-help", ejson::String(help));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
_interfaceClient->answerError(_transactionId,
|
||||
"WRONG-PARAMETER-NUMBER",
|
||||
help,
|
||||
_clientId);
|
||||
return;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
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());
|
||||
if (checkCompatibility(m_paramType[iii], _obj.getParameterType(iii)) == false) {
|
||||
_interfaceClient->answerError(_transactionId,
|
||||
"WRONG-PARAMETER-TYPE",
|
||||
std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'",
|
||||
_clientId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
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;
|
||||
std::string out;
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
JUS_ERROR("Wrong number of Parameters ...");
|
||||
out += "error:WRONG-PARAMETER-NUMBER;";
|
||||
out += "error-help:request ";
|
||||
out += etk::to_string(_params.size());
|
||||
out += " parameters and need ";
|
||||
out += etk::to_string(sizeof...(JUS_TYPES));
|
||||
out += " parameters. prototype function:";
|
||||
out += getPrototype();
|
||||
return out;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
out += "error:WRONG-PARAMETER-TYPE;";
|
||||
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
|
||||
return out;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
out = jus::executeClassCallString(tmpClass, m_function, _params);
|
||||
return out;
|
||||
jus::executeClassCall(_interfaceClient, _transactionId, _clientId, tmpClass, m_function, _obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -12,92 +12,53 @@
|
||||
#include <jus/AbstractFunction.h>
|
||||
namespace jus {
|
||||
template <class JUS_RETURN, class... JUS_TYPES>
|
||||
void executeCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_RETURN (*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
void executeCall(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
JUS_RETURN (*_func)(JUS_TYPES...),
|
||||
jus::Buffer& _obj) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
ejson::Value ret = jus::convertToJson(_func((jus::convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
JUS_RETURN ret = jus::convertToJson(_func(_obj.getParameter<JUS_TYPES>(idParam++)...));
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
ejson::Value ret = jus::convertToJson(_func(jus::convertJsonTo<JUS_TYPES>(_params[idParam--])...));
|
||||
JUS_RETURN ret = jus::convertToJson(_func(_obj.getParameter<JUS_TYPES>(idParam--)...));
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
ejson::Value ret = ejson::Null();
|
||||
JUS_RETURN ret = ejson::Null();
|
||||
#endif
|
||||
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());
|
||||
_interfaceClient->addAsync([=](TcpString* _interface) {
|
||||
_interface->answerValue(_transactionId, ret, _clientId);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template <class... JUS_TYPES>
|
||||
void executeCallJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
void (*_func)(JUS_TYPES...),
|
||||
const ejson::Array& _params) {
|
||||
void executeCall(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
void (*_func)(JUS_TYPES...),
|
||||
jus::Buffer& _obj) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
_func((jus::convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
|
||||
_func(_obj.getParameter<JUS_TYPES>(idParam++)...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
_func(jus::convertJsonTo<JUS_TYPES>(_params[idParam--])...);
|
||||
_func(_obj.getParameter<JUS_TYPES>(idParam--)...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
_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;
|
||||
_interface->answerVoid(_transactionId, _clientId);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
template <class JUS_RETURN, class... JUS_TYPES>
|
||||
std::string executeCallString(JUS_RETURN (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
return etk::to_string(_func((jus::convertStringTo<JUS_TYPES>(_params[idParam++]))...));
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
return etk::to_string(_func(jus::convertStringTo<JUS_TYPES>(_params[idParam--])...));
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
template <class... JUS_TYPES>
|
||||
std::string executeCallString(void (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
|
||||
ejson::Object out;
|
||||
#if defined(__clang__)
|
||||
// clang generate a basic warning:
|
||||
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||
int32_t idParam = 0;
|
||||
_func((jus::convertStringTo<JUS_TYPES>(_params[idParam++]))...);
|
||||
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
|
||||
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
|
||||
_func(jus::convertStringTo<JUS_TYPES>(_params[idParam--])...);
|
||||
#else
|
||||
#error Must be implemented ...
|
||||
#endif
|
||||
return "";
|
||||
}
|
||||
|
||||
template <class JUS_RETURN, class... JUS_TYPES>
|
||||
class AbstractFunctionTypeDirect: public jus::AbstractFunction {
|
||||
protected:
|
||||
@ -135,69 +96,37 @@ namespace jus {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
void executeJson(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
const ejson::Array& _params,
|
||||
void* _class) override {
|
||||
void execute(const ememory::SharedPtr<jus::TcpString>& _interfaceClient,
|
||||
uint64_t _transactionId,
|
||||
uint64_t _clientId,
|
||||
jus::Buffer& _obj,
|
||||
void* _class) override {
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
answer.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
|
||||
if (_obj.getNumberParameter() != sizeof...(JUS_TYPES)) {
|
||||
std::string help = "request ";
|
||||
help += etk::to_string(_params.size());
|
||||
help += etk::to_string(_obj.getNumberParameter());
|
||||
help += " parameters and need ";
|
||||
help += etk::to_string(sizeof...(JUS_TYPES));
|
||||
help += " parameters. prototype function:";
|
||||
help += getPrototype();
|
||||
answer.add("error-help", ejson::String(help));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
_interfaceClient->write(answer.generateMachineString());
|
||||
_interfaceClient->answerError(_transactionId,
|
||||
"WRONG-PARAMETER-NUMBER",
|
||||
help,
|
||||
_clientId);
|
||||
return;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
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());
|
||||
if (checkCompatibility(m_paramType[iii], _obj.getParameterType(iii)) == false) {
|
||||
_interfaceClient->answerError(_transactionId,
|
||||
"WRONG-PARAMETER-TYPE",
|
||||
std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'",
|
||||
_clientId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
jus::executeCallJson(_interfaceClient, _transactionId, _clientId, m_function, _params);
|
||||
}
|
||||
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
|
||||
std::string out;
|
||||
// check parameter number
|
||||
if (_params.size() != sizeof...(JUS_TYPES)) {
|
||||
JUS_ERROR("Wrong number of Parameters ...");
|
||||
out += "error:WRONG-PARAMETER-NUMBER;";
|
||||
out += "error-help:request ";
|
||||
out += etk::to_string(_params.size());
|
||||
out += " parameters and need ";
|
||||
out += etk::to_string(sizeof...(JUS_TYPES));
|
||||
out += " parameters. prototype function:";
|
||||
out += getPrototype();
|
||||
return out;
|
||||
}
|
||||
// check parameter compatibility
|
||||
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
|
||||
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
|
||||
out += "error:WRONG-PARAMETER-TYPE;";
|
||||
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
|
||||
return out;
|
||||
}
|
||||
}
|
||||
// execute cmd:
|
||||
out = jus::executeCallString(m_function, _params);
|
||||
return out;
|
||||
jus::executeCall(_interfaceClient, _transactionId, _clientId, m_function, _obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -60,19 +60,19 @@ void jus::Buffer::internalComposeWith(const uint8_t* _buffer, uint32_t _lenght)
|
||||
} else {
|
||||
// TODO : check size ...
|
||||
}
|
||||
JUS_INFO("Get binary messages " << generateHumanString());
|
||||
JUS_DEBUG("Get binary messages " << generateHumanString());
|
||||
}
|
||||
|
||||
void jus::Buffer::composeWith(const std::vector<uint8_t>& _buffer) {
|
||||
internalComposeWith(&_buffer[0], _buffer.size());
|
||||
}
|
||||
void jus::Buffer::composeWith(const std::string& _buffer) {
|
||||
internalComposeWith(reinterpret_cast<const uint8_t*>(&_buffer[0]), _buffer.size());
|
||||
fromJson(ejson::Object(_buffer));
|
||||
}
|
||||
|
||||
|
||||
void jus::Buffer::clear() {
|
||||
JUS_WARNING("clear buffer");
|
||||
JUS_VERBOSE("clear buffer");
|
||||
m_data.clear();
|
||||
m_paramOffset.clear();
|
||||
m_header.lenght = 0;
|
||||
@ -131,7 +131,7 @@ uint16_t jus::Buffer::getProtocalVersion() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setProtocolVersion(uint16_t _value) {
|
||||
JUS_WARNING("setProtocolVersion :" << _value);
|
||||
JUS_VERBOSE("setProtocolVersion :" << _value);
|
||||
m_header.versionProtocol = _value;
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ uint32_t jus::Buffer::getTransactionId() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setTransactionId(uint32_t _value) {
|
||||
JUS_WARNING("setTransactionId :" << _value);
|
||||
JUS_VERBOSE("setTransactionId :" << _value);
|
||||
m_header.transactionID = _value;
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ uint32_t jus::Buffer::getClientId() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setClientId(uint32_t _value) {
|
||||
JUS_WARNING("setClientId :" << _value);
|
||||
JUS_VERBOSE("setClientId :" << _value);
|
||||
m_header.clientID = _value;
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ uint16_t jus::Buffer::getPartId() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setPartId(uint16_t _value) {
|
||||
JUS_WARNING("setPartId :" << _value);
|
||||
JUS_VERBOSE("setPartId :" << _value);
|
||||
m_header.partID = (m_header.partID&0x8000) | (_value & 0x7FFF);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ bool jus::Buffer::getPartFinish() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setPartFinish(bool _value) {
|
||||
JUS_WARNING("setPartFinish :" << _value);
|
||||
JUS_VERBOSE("setPartFinish :" << _value);
|
||||
if (_value == true) {
|
||||
m_header.partID = (m_header.partID & 0x7FFF) | 0x8000;
|
||||
} else {
|
||||
@ -181,7 +181,7 @@ enum jus::Buffer::typeMessage jus::Buffer::getType() const {
|
||||
}
|
||||
|
||||
void jus::Buffer::setType(enum typeMessage _value) {
|
||||
JUS_WARNING("setType :" << _value);
|
||||
JUS_VERBOSE("setType :" << _value);
|
||||
m_header.typeMessage = uint16_t(_value);
|
||||
}
|
||||
|
||||
@ -2154,19 +2154,6 @@ std::vector<std::string> jus::Buffer::internalGetParameter<std::vector<std::stri
|
||||
pointer += out[iii].size() + 1;
|
||||
JUS_DEBUG(" value: '" << out[iii] << "'");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO : ...
|
||||
JUS_TODO("parse list of string ...");
|
||||
/*
|
||||
const uint8_t* tmp = reinterpret_cast<const uint8_t*>(pointer);
|
||||
int32_t nbElement = dataSize / sizeof(uint8_t);
|
||||
out.resize(nbElement);
|
||||
for (size_t iii=0; iii<nbElement; ++iii) {
|
||||
out[iii] = tmp[iii] == 'T';
|
||||
}
|
||||
*/
|
||||
return out;
|
||||
}
|
||||
JUS_ERROR("Can not get type from '" << type << "'");
|
||||
@ -2360,11 +2347,6 @@ ejson::Object jus::Buffer::toJson() const {
|
||||
return out;
|
||||
}
|
||||
|
||||
// TODO : Add protocl ERROR ...
|
||||
void jus::Buffer::fromJson(const std::string& _data) {
|
||||
return fromJson(ejson::Object(_data));
|
||||
}
|
||||
|
||||
void jus::Buffer::fromJson(const ejson::Object& _data) {
|
||||
clear();
|
||||
uint32_t valueClientId = 0;
|
||||
|
@ -192,7 +192,6 @@ namespace jus {
|
||||
void prepare();
|
||||
ejson::Object toJson() const;
|
||||
void fromJson(const ejson::Object& _data);
|
||||
void fromJson(const std::string& _data);
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, enum jus::Buffer::typeMessage _value);
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
jus::Client::Client() :
|
||||
propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Client::onPropertyChangeIp),
|
||||
propertyPort(this, "port", 1983, "Port to connect server", &jus::Client::onPropertyChangePort),
|
||||
m_interfaceMode(jus::connectionMode::modeJson),
|
||||
m_id(1) {
|
||||
m_interfaceClient.connect(this, &jus::Client::onClientData);
|
||||
}
|
||||
@ -22,7 +21,7 @@ jus::Client::~Client() {
|
||||
|
||||
}
|
||||
|
||||
void jus::Client::onClientDataRaw(jus::Buffer& _value) {
|
||||
void jus::Client::onClientData(jus::Buffer& _value) {
|
||||
JUS_DEBUG("Get answer RAW : "/* << _value*/);
|
||||
jus::FutureBase future;
|
||||
uint64_t tid = _value.getTransactionId();
|
||||
@ -85,67 +84,6 @@ void jus::Client::onClientDataRaw(jus::Buffer& _value) {
|
||||
}
|
||||
}
|
||||
|
||||
void jus::Client::onClientData(std::string _value) {
|
||||
JUS_DEBUG("Get answer : " << _value);
|
||||
ejson::Object obj(_value);
|
||||
jus::FutureBase future;
|
||||
uint64_t tid = obj["id"].toNumber().get();
|
||||
if (tid == 0) {
|
||||
if (obj["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(obj);
|
||||
}
|
||||
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()) {
|
||||
if (it->isValid() == false) {
|
||||
it = m_pendingCall.erase(it);
|
||||
continue;
|
||||
}
|
||||
if (it->getTransactionId() != tid) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
future = *it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (future.isValid() == false) {
|
||||
JUS_TODO("manage this event better ...");
|
||||
//m_newData.push_back(std::move(_value));
|
||||
return;
|
||||
}
|
||||
bool ret = future.setAnswer(obj);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jus::ServiceRemote jus::Client::getService(const std::string& _name) {
|
||||
return jus::ServiceRemote(this, _name);
|
||||
}
|
||||
@ -171,29 +109,6 @@ bool jus::Client::unlink(const uint32_t& _serviceId) {
|
||||
return ret.get();
|
||||
}
|
||||
|
||||
std::string jus::Client::asyncRead() {
|
||||
if (m_interfaceClient.isActive() == false) {
|
||||
return "";
|
||||
}
|
||||
int32_t iii = 5000;
|
||||
while (iii>0) {
|
||||
usleep(10000);
|
||||
if (m_newData.size() != 0) {
|
||||
break;
|
||||
}
|
||||
--iii;
|
||||
}
|
||||
if (iii == 0) {
|
||||
// Time-out ...
|
||||
return "";
|
||||
}
|
||||
std::string out;
|
||||
out = std::move(m_newData[0]);
|
||||
m_newData.erase(m_newData.begin());
|
||||
JUS_DEBUG("get async data: " << out);
|
||||
return out;
|
||||
}
|
||||
|
||||
void jus::Client::onPropertyChangeIp() {
|
||||
disconnect();
|
||||
}
|
||||
@ -214,9 +129,7 @@ bool jus::Client::connect(const std::string& _remoteUserToConnect){
|
||||
jus::Future<bool> retBin = call("setMode", "BIN").wait();
|
||||
if (retBin.get() == true) {
|
||||
JUS_WARNING(" ==> accepted binary");
|
||||
m_interfaceMode = jus::connectionMode::modeBinary;
|
||||
m_interfaceClient.connectClean();
|
||||
m_interfaceClient.connectRaw(this, &jus::Client::onClientDataRaw);
|
||||
m_interfaceClient.setMode(jus::connectionMode::modeBinary);
|
||||
JUS_INFO("Connection jump in BINARY ...");
|
||||
} else {
|
||||
// stay in JSON
|
||||
@ -281,8 +194,7 @@ class SendAsyncJson {
|
||||
obj.add("id", ejson::Number(m_transactionId));
|
||||
obj.add("part", ejson::Number(m_partId));
|
||||
obj.add("finish", ejson::Boolean(true));
|
||||
JUS_DEBUG("Send JSON '" << obj.generateHumanString() << "'");
|
||||
_interface->write(obj.generateMachineString());
|
||||
_interface->writeJson(obj);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -309,8 +221,7 @@ jus::FutureBase jus::Client::callJson(uint64_t _transactionId,
|
||||
if (_async.size() != 0) {
|
||||
_obj.add("part", ejson::Number(0));
|
||||
}
|
||||
JUS_DEBUG("Send JSON '" << _obj.generateHumanString() << "'");
|
||||
m_interfaceClient.write(_obj.generateMachineString());
|
||||
m_interfaceClient.writeJson(_obj);
|
||||
|
||||
if (_async.size() != 0) {
|
||||
m_interfaceClient.addAsync(SendAsyncJson(_transactionId, _serviceId, _async));
|
||||
|
@ -23,10 +23,8 @@ namespace jus {
|
||||
eproperty::Value<uint16_t> propertyPort;
|
||||
std::mutex m_mutex;
|
||||
std::vector<jus::FutureBase> m_pendingCall;
|
||||
protected:
|
||||
enum jus::connectionMode m_interfaceMode;
|
||||
public:
|
||||
enum jus::connectionMode getMode() { return m_interfaceMode; }
|
||||
enum jus::connectionMode getMode() { return m_interfaceClient.getMode(); }
|
||||
private:
|
||||
jus::TcpString m_interfaceClient;
|
||||
uint32_t m_id;
|
||||
@ -46,9 +44,7 @@ namespace jus {
|
||||
// Connect to ourself:
|
||||
//client1.authentificate("coucou");
|
||||
private:
|
||||
void onClientData(std::string _value);
|
||||
void onClientDataRaw(jus::Buffer& _value);
|
||||
std::string asyncRead();
|
||||
void onClientData(jus::Buffer& _value);
|
||||
jus::FutureBase callJson(uint64_t _transactionId,
|
||||
ejson::Object _obj,
|
||||
const std::vector<ActionAsyncClient>& _async,
|
||||
|
@ -93,6 +93,7 @@ bool jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
|
||||
tmp.fromJson(_returnValue);
|
||||
return setAnswer(tmp);
|
||||
}
|
||||
|
||||
bool jus::FutureBase::setAnswer(const jus::Buffer& _returnValue) {
|
||||
if (m_data == nullptr) {
|
||||
JUS_ERROR(" Not a valid future ...");
|
||||
@ -208,51 +209,17 @@ jus::FutureBase& jus::FutureBase::waitUntil(std::chrono::steady_clock::time_poin
|
||||
}
|
||||
|
||||
|
||||
jus::FutureCall::FutureCall(uint64_t _clientId, uint64_t _transactionId, const ejson::Object& _callValue) :
|
||||
jus::FutureCall::FutureCall(uint64_t _clientId, uint64_t _transactionId, jus::Buffer& _callValue) :
|
||||
m_transactionId(_transactionId),
|
||||
m_clientId(_clientId),
|
||||
m_isFinished(false) {
|
||||
m_data = _callValue;
|
||||
if (m_data.valueExist("part") == true) {
|
||||
if (m_data.valueExist("finish") == true) {
|
||||
if (m_data["finish"].toBoolean().get() == true) {
|
||||
m_isFinished = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_isFinished = true;
|
||||
}
|
||||
m_isFinished = m_data.getPartFinish();
|
||||
}
|
||||
|
||||
void jus::FutureCall::appendData(const ejson::Object& _callValue) {
|
||||
uint64_t paramID = _callValue["param-id"].toNumber().getU64();
|
||||
// get the previous element parameters
|
||||
ejson::Array params = m_data["param"].toArray();
|
||||
if (params.exist() == false) {
|
||||
JUS_ERROR("try to add element on an inexistand parameter ...==> bad case");
|
||||
m_isFinished = true;
|
||||
return;
|
||||
}
|
||||
// Get the specific parameter
|
||||
ejson::Object param = params[paramID].toObject();
|
||||
if (param.exist() == false) {
|
||||
JUS_ERROR("the parameter is not an object ==> bad case");
|
||||
m_isFinished = true;
|
||||
return;
|
||||
}
|
||||
// check if section data
|
||||
if (param.valueExist("data") == false) {
|
||||
param.add("data", ejson::Array());
|
||||
}
|
||||
// add data in the array (only if we have local data ...
|
||||
if (_callValue.valueExist("data") == true) {
|
||||
param["data"].toArray().add(_callValue["data"]);
|
||||
}
|
||||
if (_callValue.valueExist("finish") == true) {
|
||||
if (_callValue["finish"].toBoolean().get() == true) {
|
||||
m_isFinished = true;
|
||||
}
|
||||
}
|
||||
void jus::FutureCall::appendData(jus::Buffer& _callValue) {
|
||||
m_dataMultiplePack.push_back(_callValue);
|
||||
m_isFinished = _callValue.getPartFinish();
|
||||
}
|
||||
|
||||
uint64_t jus::FutureCall::getTransactionId() {
|
||||
@ -267,7 +234,7 @@ bool jus::FutureCall::isFinished() {
|
||||
return m_isFinished;
|
||||
}
|
||||
|
||||
ejson::Object jus::FutureCall::getRaw() {
|
||||
jus::Buffer& jus::FutureCall::getRaw() {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
|
@ -38,17 +38,18 @@ namespace jus {
|
||||
uint64_t m_transactionId;
|
||||
uint64_t m_clientId;
|
||||
bool m_isFinished;
|
||||
ejson::Object m_data;
|
||||
jus::Buffer m_data;
|
||||
std::vector<jus::Buffer> m_dataMultiplePack;
|
||||
std::chrono::steady_clock::time_point m_receiveTime;
|
||||
std::chrono::steady_clock::time_point m_answerTime;
|
||||
public:
|
||||
FutureCall(uint64_t _clientId, uint64_t _transactionId, const ejson::Object& _callValue);
|
||||
void appendData(const ejson::Object& _callValue);
|
||||
FutureCall(uint64_t _clientId, uint64_t _transactionId, jus::Buffer& _callValue);
|
||||
void appendData(jus::Buffer& _callValue);
|
||||
uint64_t getTransactionId();
|
||||
uint64_t getClientId();
|
||||
bool isFinished();
|
||||
std::chrono::nanoseconds getTransmitionTime();
|
||||
ejson::Object getRaw();
|
||||
jus::Buffer& getRaw();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ std::vector<std::string> jus::GateWay::getAllServiceName() {
|
||||
}
|
||||
|
||||
|
||||
void jus::GateWay::answer(uint64_t _userSessionId, ejson::Object _data) {
|
||||
void jus::GateWay::answer(uint64_t _userSessionId, jus::Buffer& _data) {
|
||||
for (auto &it : m_clientList) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
|
@ -33,7 +33,7 @@ namespace jus {
|
||||
void stop();
|
||||
ememory::SharedPtr<jus::GateWayService> get(const std::string& _serviceName);
|
||||
std::vector<std::string> getAllServiceName();
|
||||
void answer(uint64_t _userSessionId, ejson::Object _data);
|
||||
void answer(uint64_t _userSessionId, jus::Buffer& _data);
|
||||
void newService(enet::Tcp _connection);
|
||||
void newClient(enet::Tcp _connection);
|
||||
void cleanIO();
|
||||
|
@ -19,7 +19,6 @@ jus::GateWayClient::GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayI
|
||||
m_state(jus::GateWayClient::state::unconnect),
|
||||
m_gatewayInterface(_gatewayInterface),
|
||||
m_interfaceClient(std::move(_connection)),
|
||||
m_interfaceMode(jus::connectionMode::modeJson),
|
||||
m_transactionLocalId(1) {
|
||||
JUS_INFO("----------------");
|
||||
JUS_INFO("-- NEW Client --");
|
||||
@ -71,42 +70,13 @@ bool jus::GateWayClient::isAlive() {
|
||||
}
|
||||
|
||||
void jus::GateWayClient::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
|
||||
answerError(_transactionId, protocolError, _errorHelp);
|
||||
m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp);
|
||||
m_state = jus::GateWayClient::state::disconnect;
|
||||
m_interfaceClient.disconnect(true);
|
||||
}
|
||||
/*
|
||||
void jus::GateWayClient::answerValue(int32_t _transactionId, bool _value) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("return", ejson::Boolean(_value));
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
}
|
||||
*/
|
||||
|
||||
void jus::GateWayClient::answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorHelp) {
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
ejson::Object answer;
|
||||
answer.add("error", ejson::String(protocolError));
|
||||
answer.add("id", ejson::Number(_clientTransactionId));
|
||||
answer.add("error-help", ejson::String(_errorHelp));
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
jus::Buffer answer;
|
||||
answer.setType(jus::Buffer::typeMessage::answer);
|
||||
answer.setTransactionId(_clientTransactionId);
|
||||
answer.addError(protocolError, _errorHelp);
|
||||
m_interfaceClient.writeBinary(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("TODO ... ");
|
||||
} else {
|
||||
JUS_ERROR("wrong type of communication");
|
||||
}
|
||||
}
|
||||
|
||||
void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
void jus::GateWayClient::onClientData(jus::Buffer& _value) {
|
||||
uint32_t transactionId = _value.getTransactionId();
|
||||
if (transactionId == 0) {
|
||||
JUS_ERROR("Protocol error ==>missing id");
|
||||
@ -137,20 +107,16 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
std::string mode = _value.getParameter<std::string>(0);
|
||||
if (mode == "JSON") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: JSON");
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceMode = jus::connectionMode::modeJson;
|
||||
m_interfaceClient.connectCleanRaw();
|
||||
m_interfaceClient.connect(this, &jus::GateWayClient::onClientData);
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
m_interfaceClient.setMode(jus::connectionMode::modeJson);
|
||||
} else if (mode == "BIN") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: BINARY");
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceMode = jus::connectionMode::modeBinary;
|
||||
m_interfaceClient.connectClean();
|
||||
m_interfaceClient.connectRaw(this, &jus::GateWayClient::onClientDataRaw);
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
m_interfaceClient.setMode(jus::connectionMode::modeBinary);
|
||||
} else if (mode == "XML") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: XML");
|
||||
//m_interfaceMode = jus::connectionMode::modeXml;
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
} else {
|
||||
answerProtocolError(transactionId, std::string("Call setMode with unknow argument : '") /*+ etk::to_string(int32_t(mode))*/ + "' supported [JSON/XML/BIN]");
|
||||
}
|
||||
@ -168,7 +134,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
jus::Future<bool> futLocalService = call(m_uid2, m_userService, "_new", m_userConnectionName, "**Gateway**", std::vector<std::string>());
|
||||
futLocalService.wait(); // TODO: Set timeout ...
|
||||
m_state = jus::GateWayClient::state::userIdentify;
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -199,11 +165,11 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
fut.wait(); // TODO: Set timeout ...
|
||||
if (fut.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
@ -215,11 +181,11 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
fut.wait(); // TODO: Set timeout ...
|
||||
if (fut.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
@ -235,7 +201,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
futGroup.wait(); // TODO: Set timeout ...
|
||||
if (futGroup.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "grouping error");
|
||||
return;
|
||||
}
|
||||
@ -248,7 +214,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
futServices.wait(); // TODO: Set timeout ...
|
||||
if (futServices.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "service filtering error");
|
||||
return;
|
||||
}
|
||||
@ -258,7 +224,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
JUS_WARNING(" services: " << etk::to_string(m_clientServices));
|
||||
|
||||
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
m_state = jus::GateWayClient::state::clientIdentify;
|
||||
return;
|
||||
}
|
||||
@ -269,11 +235,11 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
if (serviceId == 0) {
|
||||
// This is 2 default service for the cient interface that manage the authorisation of view:
|
||||
if (callFunction == "getServiceCount") {
|
||||
answerValue(transactionId, m_clientServices.size());
|
||||
m_interfaceClient.answerValue(transactionId, m_clientServices.size());
|
||||
return;
|
||||
}
|
||||
if (callFunction == "getServiceList") {
|
||||
answerValue(transactionId, m_clientServices);
|
||||
m_interfaceClient.answerValue(transactionId, m_clientServices);
|
||||
//listService.add(ejson::String("ServiceManager/v0.1.0"));
|
||||
return;
|
||||
}
|
||||
@ -296,7 +262,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
if (it == m_listConnectedService.end()) {
|
||||
// check if service is connectable ...
|
||||
if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) {
|
||||
answerError(transactionId, "UN-AUTHORIZED-SERVICE");
|
||||
m_interfaceClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE");
|
||||
return;
|
||||
}
|
||||
ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName);
|
||||
@ -305,17 +271,17 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
futLink.wait(); // TODO: Set timeout ...
|
||||
if (futLink.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ... LINK");
|
||||
answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
return;
|
||||
}
|
||||
m_listConnectedService.push_back(srv);
|
||||
answerValue(transactionId, m_listConnectedService.size());
|
||||
m_interfaceClient.answerValue(transactionId, m_listConnectedService.size());
|
||||
return;
|
||||
}
|
||||
answerError(transactionId, "CAN-NOT-CONNECT-SERVICE");
|
||||
m_interfaceClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE");
|
||||
return;
|
||||
}
|
||||
answerError(transactionId, "SERVICE-ALREADY-CONNECTED");;
|
||||
m_interfaceClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");;
|
||||
return;
|
||||
}
|
||||
if (callFunction == "unlink") {
|
||||
@ -323,28 +289,28 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
int64_t localServiceID = _value.getParameter<int64_t>(0)-1;
|
||||
// Check if service already link:
|
||||
if (localServiceID >= m_listConnectedService.size()) {
|
||||
answerError(transactionId, "NOT-CONNECTED-SERVICE");
|
||||
m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
|
||||
return;
|
||||
}
|
||||
jus::Future<bool> futUnLink = call(m_uid, m_listConnectedService[localServiceID], "_delete");
|
||||
futUnLink.wait(); // TODO: Set timeout ...
|
||||
if (futUnLink.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ... UNLINK");
|
||||
answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
return;
|
||||
}
|
||||
m_listConnectedService[localServiceID] = nullptr;
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
return;
|
||||
}
|
||||
JUS_ERROR("Function does not exist ... '" << callFunction << "'");
|
||||
answerError(transactionId, "CALL-UNEXISTING");
|
||||
m_interfaceClient.answerError(transactionId, "CALL-UNEXISTING");
|
||||
return;
|
||||
}
|
||||
// decrease service ID ...
|
||||
serviceId -= 1;
|
||||
if (serviceId >= m_listConnectedService.size()) {
|
||||
answerError(transactionId, "NOT-CONNECTED-SERVICE");
|
||||
m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
|
||||
return;
|
||||
} else {
|
||||
if (m_listConnectedService[serviceId] == nullptr) {
|
||||
@ -388,8 +354,7 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << transactionId);
|
||||
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
|
||||
tmpp["id"].toNumber().set(uint64_t(transactionId));
|
||||
JUS_DEBUG("transmit=" << tmpp.generateMachineString());
|
||||
m_interfaceClient.write(tmpp.generateMachineString());
|
||||
m_interfaceClient.writeJson(tmpp);
|
||||
if (tmpp.valueExist("part") == true) {
|
||||
// multiple send element ...
|
||||
if (tmpp.valueExist("finish") == true) {
|
||||
@ -405,341 +370,6 @@ void jus::GateWayClient::onClientDataRaw(jus::Buffer& _value) {
|
||||
}
|
||||
}
|
||||
|
||||
void jus::GateWayClient::onClientData(std::string _value) {
|
||||
JUS_DEBUG("On data: " << _value);
|
||||
jus::Buffer tmp;
|
||||
tmp.fromJson(_value);
|
||||
onClientDataRaw(tmp);
|
||||
|
||||
#ifdef SDFGSDFSFDSFSDFSDF
|
||||
ejson::Object data(_value);
|
||||
uint64_t transactionId = data["id"].toNumber().getU64();
|
||||
if (transactionId == 0) {
|
||||
JUS_ERROR("Protocol error ==>missing id");
|
||||
answerProtocolError(transactionId, "missing parameter: 'id'");
|
||||
return;
|
||||
}
|
||||
std::string callFunction = data["call"].toString().get();
|
||||
switch (m_state) {
|
||||
case jus::GateWayClient::state::disconnect:
|
||||
case jus::GateWayClient::state::unconnect:
|
||||
{
|
||||
JUS_ERROR("Must never appear");
|
||||
answerProtocolError(transactionId, "Gateway internal error");
|
||||
return;
|
||||
}
|
||||
case jus::GateWayClient::state::connect:
|
||||
{
|
||||
if (m_userConnectionName != "") {
|
||||
answerProtocolError(transactionId, "Gateway internal error 2");
|
||||
return;
|
||||
}
|
||||
if (callFunction == "setMode") {
|
||||
std::string mode = data["param"].toArray()[0].toString().get();
|
||||
if (mode == "JSON") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: JSON");
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceMode = jus::connectionMode::modeJson;
|
||||
m_interfaceClient.connectCleanRaw();
|
||||
m_interfaceClient.connect(this, &jus::GateWayClient::onClientData);
|
||||
} else if (mode == "BIN") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: BINARY");
|
||||
answerValue(transactionId, true);
|
||||
m_interfaceMode = jus::connectionMode::modeBinary;
|
||||
m_interfaceClient.connectClean();
|
||||
m_interfaceClient.connectRaw(this, &jus::GateWayClient::onClientDataRaw);
|
||||
} else if (mode == "XML") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: XML");
|
||||
//m_interfaceMode = jus::connectionMode::modeXml;
|
||||
answerValue(transactionId, false);
|
||||
} else {
|
||||
answerProtocolError(transactionId, std::string("Call setMode with unknow argument : '") /*+ etk::to_string(int32_t(mode))*/ + "' supported [JSON/XML/BIN]");
|
||||
}
|
||||
return;
|
||||
} else if (callFunction == "connectToUser") {
|
||||
m_userConnectionName = data["param"].toArray()[0].toString().get();
|
||||
if (m_userConnectionName == "") {
|
||||
answerProtocolError(transactionId, "Call connectToUser with no parameter 'user'");
|
||||
} else {
|
||||
JUS_WARNING("[" << m_uid << "] Set client connect to user : '" << m_userConnectionName << "'");
|
||||
|
||||
m_userService = m_gatewayInterface->get("system-user");
|
||||
if (m_userService == nullptr) {
|
||||
answerProtocolError(transactionId, "Gateway internal error 'No user interface'");
|
||||
} else {
|
||||
jus::Future<bool> futLocalService = call(m_uid2, m_userService, "_new", m_userConnectionName, "**Gateway**", std::vector<std::string>());
|
||||
futLocalService.wait(); // TODO: Set timeout ...
|
||||
m_state = jus::GateWayClient::state::userIdentify;
|
||||
answerValue(transactionId, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
JUS_WARNING("[" << m_uid << "] Client must send conection to user name ...");
|
||||
answerProtocolError(transactionId, "Missing call of connectToUser");
|
||||
return;
|
||||
}
|
||||
case jus::GateWayClient::state::userIdentify:
|
||||
{
|
||||
m_clientServices.clear();
|
||||
m_clientgroups.clear();
|
||||
m_clientName.clear();
|
||||
|
||||
if ( callFunction != "identify"
|
||||
&& callFunction != "auth"
|
||||
&& callFunction != "anonymous") {
|
||||
answerProtocolError(transactionId, "Client must call: identify/auth/anonymous");
|
||||
return;
|
||||
}
|
||||
if (callFunction == "identify") {
|
||||
std::string clientName = data["param"].toArray()[0].toString().get();
|
||||
std::string clientTocken = data["param"].toArray()[1].toString().get();
|
||||
if (m_userService == nullptr) {
|
||||
answerProtocolError(transactionId, "gateWay internal error 3");
|
||||
return;
|
||||
}
|
||||
jus::Future<bool> fut = call(m_uid2, m_userService, "checkTocken", clientName, clientTocken);
|
||||
fut.wait(); // TODO: Set timeout ...
|
||||
if (fut.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
m_clientName = clientName;
|
||||
}
|
||||
if (callFunction == "auth") {
|
||||
std::string password = data["param"].toArray()[0].toString().get();
|
||||
jus::Future<bool> fut = call(m_uid2, m_userService, "checkAuth", password);
|
||||
fut.wait(); // TODO: Set timeout ...
|
||||
if (fut.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
m_clientName = m_userConnectionName;
|
||||
}
|
||||
if (callFunction == "anonymous") {
|
||||
m_clientName = "";
|
||||
}
|
||||
// --------------------------------
|
||||
// -- Get groups:
|
||||
// --------------------------------
|
||||
jus::Future<std::vector<std::string>> futGroup = call(m_uid2, m_userService, "getGroups", m_clientName);
|
||||
futGroup.wait(); // TODO: Set timeout ...
|
||||
if (futGroup.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "grouping error");
|
||||
return;
|
||||
}
|
||||
m_clientgroups = futGroup.get();
|
||||
// --------------------------------
|
||||
// -- Get services:
|
||||
// --------------------------------
|
||||
std::vector<std::string> currentServices = m_gatewayInterface->getAllServiceName();
|
||||
jus::Future<std::vector<std::string>> futServices = call(m_uid2, m_userService, "filterServices", m_clientName, currentServices);
|
||||
futServices.wait(); // TODO: Set timeout ...
|
||||
if (futServices.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "service filtering error");
|
||||
return;
|
||||
}
|
||||
m_clientServices = futServices.get();
|
||||
JUS_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'");
|
||||
JUS_WARNING(" groups: " << etk::to_string(m_clientgroups));
|
||||
JUS_WARNING(" services: " << etk::to_string(m_clientServices));
|
||||
|
||||
|
||||
answerValue(transactionId, true);
|
||||
m_state = jus::GateWayClient::state::clientIdentify;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case jus::GateWayClient::state::clientIdentify:
|
||||
{
|
||||
ejson::Number numService = data["service"].toNumber();
|
||||
if ( numService.exist() == false
|
||||
|| numService.getU64() == 0) {
|
||||
// This is 2 default service for the cient interface that manage the authorisation of view:
|
||||
if (callFunction == "getServiceCount") {
|
||||
answerValue(transactionId, m_clientServices.size());
|
||||
return;
|
||||
}
|
||||
if (callFunction == "getServiceList") {
|
||||
answerValue(transactionId, m_clientServices);
|
||||
//listService.add(ejson::String("ServiceManager/v0.1.0"));
|
||||
return;
|
||||
}
|
||||
if (callFunction == "link") {
|
||||
// first param:
|
||||
std::string serviceName = data["param"].toArray()[0].toString().get();
|
||||
// Check if service already link:
|
||||
auto it = m_listConnectedService.begin();
|
||||
while (it != m_listConnectedService.end()) {
|
||||
if (*it == nullptr) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
if ((*it)->getName() != serviceName) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (it == m_listConnectedService.end()) {
|
||||
// check if service is connectable ...
|
||||
if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) {
|
||||
answerError(transactionId, "UN-AUTHORIZED-SERVICE");
|
||||
return;
|
||||
}
|
||||
ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName);
|
||||
if (srv != nullptr) {
|
||||
jus::Future<bool> futLink = call(m_uid, srv, "_new", m_userConnectionName, m_clientName, m_clientgroups);
|
||||
futLink.wait(); // TODO: Set timeout ...
|
||||
if (futLink.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ... LINK");
|
||||
answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
return;
|
||||
}
|
||||
m_listConnectedService.push_back(srv);
|
||||
answerValue(transactionId, m_listConnectedService.size());
|
||||
return;
|
||||
}
|
||||
answerError(transactionId, "CAN-NOT-CONNECT-SERVICE");
|
||||
return;
|
||||
}
|
||||
answerError(transactionId, "SERVICE-ALREADY-CONNECTED");;
|
||||
return;
|
||||
}
|
||||
if (callFunction == "unlink") {
|
||||
// first param:
|
||||
int64_t localServiceID = data["param"].toArray()[0].toNumber().getI64()-1;
|
||||
// Check if service already link:
|
||||
if (localServiceID >= m_listConnectedService.size()) {
|
||||
answerError(transactionId, "NOT-CONNECTED-SERVICE");
|
||||
return;
|
||||
}
|
||||
jus::Future<bool> futUnLink = call(m_uid, m_listConnectedService[localServiceID], "_delete");
|
||||
futUnLink.wait(); // TODO: Set timeout ...
|
||||
if (futUnLink.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ... UNLINK");
|
||||
answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
|
||||
return;
|
||||
}
|
||||
m_listConnectedService[localServiceID] = nullptr;
|
||||
answerValue(transactionId, true);
|
||||
return;
|
||||
}
|
||||
JUS_ERROR("Function does not exist ... '" << callFunction << "'");
|
||||
answerError(transactionId, "CALL-UNEXISTING");
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t serviceId = numService.getU64()-1;
|
||||
if (serviceId >= m_listConnectedService.size()) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", data["id"]);
|
||||
answer.add("error", ejson::String("NOT-CONNECTED-SERVICE"));
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
return;
|
||||
} else {
|
||||
bool finish = false;
|
||||
if (data.valueExist("finish") == true) {
|
||||
finish = data["finish"].toBoolean().get();
|
||||
}
|
||||
int64_t partTmp = -1;
|
||||
if (data.valueExist("part") == true) {
|
||||
uint64_t part = data["part"].toNumber().getU64();
|
||||
partTmp = part;
|
||||
if (part != 0) {
|
||||
// subMessage ... ==> try to forward message:
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
for (auto &itCall : m_pendingCall) {
|
||||
JUS_INFO(" compare : " << itCall.first << " =?= " << transactionId);
|
||||
if (itCall.first == transactionId) {
|
||||
// Find element ==> transit it ...
|
||||
if (m_listConnectedService[serviceId] == nullptr) {
|
||||
// TODO ...
|
||||
} else {
|
||||
ejson::Object obj;
|
||||
obj.add("id", ejson::Number(itCall.second.getTransactionId()));
|
||||
obj.add("param-id", data["param-id"]);
|
||||
obj.add("part", ejson::Number(part));
|
||||
obj.add("data", data["data"]);
|
||||
if (finish == true) {
|
||||
obj.add("finish", ejson::Boolean(true));
|
||||
}
|
||||
m_listConnectedService[serviceId]->SendData(m_uid, obj);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
JUS_ERROR("Can not transfer part of a message ...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
callActionForward(m_uid,
|
||||
transactionId,
|
||||
m_listConnectedService[serviceId],
|
||||
data["call"].toString().get(),
|
||||
data["param"].toArray(),
|
||||
[=](jus::FutureBase _ret) {
|
||||
ejson::Object tmpp = _ret.getRaw();
|
||||
JUS_VERBOSE(" ==> transmit : " << tmpp["id"].toNumber().getU64() << " -> " << data["id"].toNumber().getU64());
|
||||
JUS_VERBOSE(" msg=" << tmpp.generateMachineString());
|
||||
tmpp["id"].toNumber().set(transactionId);
|
||||
JUS_DEBUG("transmit=" << 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;
|
||||
},
|
||||
partTmp,
|
||||
finish);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
jus::FutureBase jus::GateWayClient::callActionForward(uint64_t _callerId,
|
||||
uint64_t _clientTransactionId,
|
||||
ememory::SharedPtr<jus::GateWayService> _srv,
|
||||
const std::string& _functionName,
|
||||
ejson::Array _params,
|
||||
jus::FutureData::ObserverFinish _callback,
|
||||
int64_t _part,
|
||||
bool _finish) {
|
||||
uint64_t id = getId();
|
||||
ejson::Object callElem = jus::createCallJson(id, _functionName, _params);
|
||||
if (_part != -1) {
|
||||
callElem.add("part", ejson::Number(uint64_t(_part)));
|
||||
}
|
||||
if (_finish == true) {
|
||||
callElem.add("finish", ejson::Boolean(true));
|
||||
}
|
||||
jus::FutureBase ret = callJson(_callerId, _srv, _clientTransactionId, id, callElem, _callback);
|
||||
ret.setSynchronous();
|
||||
return ret;
|
||||
}
|
||||
|
||||
jus::FutureBase jus::GateWayClient::callBinary(uint64_t _callerId,
|
||||
ememory::SharedPtr<jus::GateWayService> _srv,
|
||||
uint64_t _clientTransactionId,
|
||||
@ -809,10 +439,11 @@ jus::FutureBase jus::GateWayClient::callJson(uint64_t _callerId,
|
||||
|
||||
|
||||
|
||||
void jus::GateWayClient::returnMessage(ejson::Object _data) {
|
||||
void jus::GateWayClient::returnMessage(jus::Buffer& _data) {
|
||||
jus::FutureBase future;
|
||||
uint64_t tid = _data["id"].toNumber().get();
|
||||
uint32_t tid = _data.getTransactionId();
|
||||
if (tid == 0) {
|
||||
/* TODO ...
|
||||
if (_data["error"].toString().get() == "PROTOCOL-ERROR") {
|
||||
JUS_ERROR("Get a Protocol error ...");
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
@ -826,6 +457,7 @@ void jus::GateWayClient::returnMessage(ejson::Object _data) {
|
||||
} else {
|
||||
JUS_ERROR("call with no ID ==> error ...");
|
||||
}
|
||||
*/
|
||||
return;
|
||||
}
|
||||
{
|
||||
|
@ -30,10 +30,10 @@ namespace jus {
|
||||
private:
|
||||
jus::GateWay* m_gatewayInterface;
|
||||
jus::TcpString m_interfaceClient;
|
||||
protected:
|
||||
enum jus::connectionMode m_interfaceMode;
|
||||
public:
|
||||
enum jus::connectionMode getMode() { return m_interfaceMode; }
|
||||
enum jus::connectionMode getMode() {
|
||||
return m_interfaceClient.getMode();
|
||||
}
|
||||
public:
|
||||
esignal::Signal<bool> signalIsConnected;
|
||||
ememory::SharedPtr<jus::GateWayService> m_userService;
|
||||
@ -49,9 +49,8 @@ namespace jus {
|
||||
virtual ~GateWayClient();
|
||||
void start(uint64_t _uid, uint64_t _uid2);
|
||||
void stop();
|
||||
void onClientDataRaw(jus::Buffer& _value);
|
||||
void onClientData(std::string _value);
|
||||
void returnMessage(ejson::Object _data);
|
||||
void onClientData(jus::Buffer& _value);
|
||||
void returnMessage(jus::Buffer& _data);
|
||||
bool checkId(uint64_t _id) const {
|
||||
return m_uid == _id
|
||||
|| m_uid2 == _id;
|
||||
@ -63,7 +62,12 @@ namespace jus {
|
||||
std::mutex m_mutex;
|
||||
std::vector<std::pair<uint64_t, jus::FutureBase>> m_pendingCall;
|
||||
int32_t m_transactionLocalId;
|
||||
jus::FutureBase callJson(uint64_t _callerId, ememory::SharedPtr<jus::GateWayService> _srv, uint64_t _clientTransactionId, uint64_t _transactionId, const ejson::Object& _obj, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
jus::FutureBase callJson(uint64_t _callerId,
|
||||
ememory::SharedPtr<jus::GateWayService> _srv,
|
||||
uint64_t _clientTransactionId,
|
||||
uint64_t _transactionId,
|
||||
const ejson::Object& _obj,
|
||||
jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
jus::FutureBase callBinary(uint64_t _callerId,
|
||||
ememory::SharedPtr<jus::GateWayService> _srv,
|
||||
uint64_t _clientTransactionId,
|
||||
@ -101,40 +105,15 @@ namespace jus {
|
||||
int64_t _part,
|
||||
bool _finish);
|
||||
|
||||
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
|
||||
|
||||
template<class JUS_ARG>
|
||||
void answerValue(uint64_t _clientTransactionId, JUS_ARG _value) {
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_clientTransactionId));
|
||||
std::vector<ActionAsyncClient> asyncAction;
|
||||
answer.add("return", jus::convertToJson(asyncAction, -1, _value));
|
||||
if (asyncAction.size() != 0) {
|
||||
JUS_ERROR("ASYNC datas ... TODO ///");
|
||||
}
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
jus::Buffer answer;
|
||||
answer.setType(jus::Buffer::typeMessage::answer);
|
||||
answer.setTransactionId(_clientTransactionId);
|
||||
answer.addAnswer(_value);
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.writeBinary(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("TODO ... ");
|
||||
} else {
|
||||
JUS_ERROR("wrong type of communication");
|
||||
}
|
||||
}
|
||||
|
||||
void answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorComment="");
|
||||
|
||||
jus::FutureBase callActionForward(ememory::SharedPtr<jus::GateWayService> _srv,
|
||||
jus::Buffer& _Buffer,
|
||||
jus::FutureData::ObserverFinish _callback);
|
||||
|
||||
|
||||
|
||||
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,10 +9,14 @@
|
||||
#include <jus/GateWay.h>
|
||||
#include <ejson/ejson.h>
|
||||
|
||||
// todo : cHANGE THIS ...
|
||||
static const std::string protocolError = "PROTOCOL-ERROR";
|
||||
|
||||
|
||||
|
||||
jus::GateWayService::GateWayService(enet::Tcp _connection, jus::GateWay* _gatewayInterface) :
|
||||
m_gatewayInterface(_gatewayInterface),
|
||||
m_interfaceClient(std::move(_connection)),
|
||||
m_interfaceMode(jus::connectionMode::modeJson) {
|
||||
m_interfaceClient(std::move(_connection)) {
|
||||
JUS_INFO("-----------------");
|
||||
JUS_INFO("-- NEW Service --");
|
||||
JUS_INFO("-----------------");
|
||||
@ -41,61 +45,89 @@ void jus::GateWayService::stop() {
|
||||
|
||||
void jus::GateWayService::SendData(uint64_t _userSessionId, ejson::Object _data) {
|
||||
_data.add("client-id", ejson::Number(_userSessionId));
|
||||
JUS_DEBUG("Send Service: " << _data.generateHumanString());
|
||||
m_interfaceClient.write(_data.generateMachineString());
|
||||
m_interfaceClient.writeJson(_data);
|
||||
}
|
||||
|
||||
void jus::GateWayService::SendData(uint64_t _userSessionId, jus::Buffer& _data) {
|
||||
_data.setClientId(_userSessionId);
|
||||
_data.prepare();
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
JUS_ERROR("NOT manage transcriptioon binary to JSON ... ");
|
||||
if (m_interfaceClient.getMode() == jus::connectionMode::modeJson) {
|
||||
ejson::Object obj = _data.toJson();
|
||||
JUS_DEBUG("Send Service: " << obj.generateHumanString());
|
||||
m_interfaceClient.write(obj.generateMachineString());
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
m_interfaceClient.writeJson(obj);
|
||||
} else if (m_interfaceClient.getMode() == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("NOT manage transcriptioon binary to XML ... ");
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
} else if (m_interfaceClient.getMode() == jus::connectionMode::modeBinary) {
|
||||
m_interfaceClient.writeBinary(_data);
|
||||
} else {
|
||||
JUS_ERROR("NOT manage transcriptioon binary to ??? mode ... ");
|
||||
}
|
||||
}
|
||||
|
||||
void jus::GateWayService::onServiceData(std::string _value) {
|
||||
JUS_DEBUG("On service data: " << _value);
|
||||
ejson::Object data(_value);
|
||||
data.add("from-service", ejson::String(m_name));
|
||||
if (data.valueExist("event") == true) {
|
||||
// No need to have a user ID ...
|
||||
if (data["event"].toString().get() == "IS-ALIVE") {
|
||||
JUS_VERBOSE("Service Alive ...");
|
||||
if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(20)) {
|
||||
m_interfaceClient.write("{\"event\":\"IS-ALIVE\"}");
|
||||
void jus::GateWayService::onServiceData(jus::Buffer& _value) {
|
||||
//JUS_DEBUG("On service data: " << _value);
|
||||
uint32_t transactionId = _value.getTransactionId();
|
||||
//data.add("from-service", ejson::String(m_name));
|
||||
if (_value.getType() == jus::Buffer::typeMessage::event) {
|
||||
/*
|
||||
if (data.valueExist("event") == true) {
|
||||
// No need to have a user ID ...
|
||||
if (data["event"].toString().get() == "IS-ALIVE") {
|
||||
JUS_VERBOSE("Service Alive ...");
|
||||
if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(20)) {
|
||||
ejson::Object tmpp;
|
||||
tmpp.add("event", ejson::String("IS-ALIVE"));
|
||||
m_interfaceClient.writeJson(tmpp);
|
||||
}
|
||||
} else {
|
||||
JUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
|
||||
}
|
||||
} else {
|
||||
JUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (data.valueExist("connect-service") == true) {
|
||||
if (m_name != "") {
|
||||
JUS_WARNING("Service interface ==> try change the servie name after init: '" << data["connect-service"].toString().get());
|
||||
// TODO : Return something ...
|
||||
return;
|
||||
}
|
||||
m_name = data["connect-service"].toString().get();
|
||||
m_interfaceClient.setInterfaceName("srv-" + m_name);
|
||||
JUS_WARNING("Service name configured");
|
||||
// TODO : Return something ...
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (data.valueExist("client-id") == false) {
|
||||
if (_value.getType() == jus::Buffer::typeMessage::call) {
|
||||
std::string callFunction = _value.getCall();
|
||||
if (callFunction == "setMode") {
|
||||
std::string mode = _value.getParameter<std::string>(0);
|
||||
if (mode == "JSON") {
|
||||
JUS_WARNING("Change mode in: JSON");
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
m_interfaceClient.setMode(jus::connectionMode::modeJson);
|
||||
} else if (mode == "BIN") {
|
||||
JUS_WARNING("Change mode in: BINARY");
|
||||
m_interfaceClient.answerValue(transactionId, true);
|
||||
m_interfaceClient.setMode(jus::connectionMode::modeBinary);
|
||||
} else if (mode == "XML") {
|
||||
JUS_WARNING("Change mode in: XML");
|
||||
//m_interfaceMode = jus::connectionMode::modeXml;
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
} else {
|
||||
answerProtocolError(transactionId, std::string("Call setMode with unknow argument : '") /*+ etk::to_string(int32_t(mode))*/ + "' supported [JSON/XML/BIN]");
|
||||
}
|
||||
return;
|
||||
} else if (callFunction == "connect-service") {
|
||||
if (m_name != "") {
|
||||
JUS_WARNING("Service interface ==> try change the servie name after init: '" << _value.getParameter<std::string>(0));
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
return;
|
||||
}
|
||||
m_name = _value.getParameter<std::string>(0);
|
||||
m_interfaceClient.setInterfaceName("srv-" + m_name);
|
||||
m_interfaceClient.answerValue(transactionId, false);
|
||||
return;
|
||||
}
|
||||
answerProtocolError(transactionId, "unknow function");
|
||||
}
|
||||
if (_value.getClientId() == 0) {
|
||||
JUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'");
|
||||
return;
|
||||
}
|
||||
uint64_t userSessionId = data["client-id"].toNumber().getU64();
|
||||
data.remove("client-id");
|
||||
data.remove("action");
|
||||
m_gatewayInterface->answer(userSessionId, data);
|
||||
m_gatewayInterface->answer(_value.getClientId(), _value);
|
||||
}
|
||||
|
||||
|
||||
void jus::GateWayService::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
|
||||
m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp);
|
||||
m_interfaceClient.disconnect(true);
|
||||
}
|
@ -18,7 +18,6 @@ namespace jus {
|
||||
jus::GateWay* m_gatewayInterface;
|
||||
jus::TcpString m_interfaceClient;
|
||||
std::string m_name;
|
||||
enum jus::connectionMode m_interfaceMode;
|
||||
public:
|
||||
esignal::Signal<bool> signalIsConnected;
|
||||
public:
|
||||
@ -26,7 +25,7 @@ namespace jus {
|
||||
virtual ~GateWayService();
|
||||
void start();
|
||||
void stop();
|
||||
void onServiceData(std::string _value);
|
||||
void onServiceData(jus::Buffer& _value);
|
||||
public:
|
||||
void SendData(uint64_t _userSessionId, ejson::Object _data);
|
||||
void SendData(uint64_t _userSessionId, jus::Buffer& _data);
|
||||
@ -34,6 +33,8 @@ namespace jus {
|
||||
return m_name;
|
||||
}
|
||||
bool isAlive();
|
||||
protected:
|
||||
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,29 +34,27 @@ std::vector<std::string> jus::Service::getExtention() {
|
||||
}
|
||||
|
||||
|
||||
void jus::Service::onClientData(std::string _value) {
|
||||
JUS_INFO("Request: " << _value);
|
||||
ejson::Object request(_value);
|
||||
uint64_t tmpID = request["id"].toNumber().getU64();
|
||||
uint64_t clientId = request["client-id"].toNumber().getU64();
|
||||
void jus::Service::onClientData(jus::Buffer& _value) {
|
||||
uint32_t tmpID = _value.getTransactionId();
|
||||
uint32_t clientId = _value.getClientId();;
|
||||
auto it = m_callMultiData.begin();
|
||||
while (it != m_callMultiData.end()) {
|
||||
if ( it->getTransactionId() == tmpID
|
||||
&& it->getClientId() == clientId) {
|
||||
JUS_WARNING("Append data ... " << tmpID);
|
||||
it->appendData(request);
|
||||
it->appendData(_value);
|
||||
if (it->isFinished() == true) {
|
||||
JUS_WARNING("CALL Function ...");
|
||||
callJson(tmpID, it->getRaw());
|
||||
callBinary(tmpID, it->getRaw());
|
||||
it = m_callMultiData.erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
jus::FutureCall futCall(clientId, tmpID, request);
|
||||
jus::FutureCall futCall(clientId, tmpID, _value);
|
||||
if (futCall.isFinished() == true) {
|
||||
callJson(tmpID, futCall.getRaw());
|
||||
callBinary(tmpID, futCall.getRaw());
|
||||
} else {
|
||||
m_callMultiData.push_back(futCall);
|
||||
}
|
||||
@ -81,7 +79,13 @@ void jus::Service::connect(const std::string& _serviceName, uint32_t _numberRetr
|
||||
}
|
||||
m_interfaceClient->setInterface(std::move(connection));
|
||||
m_interfaceClient->connect();
|
||||
m_interfaceClient->write(std::string("{\"connect-service\":\"") + _serviceName + "\"}");
|
||||
ejson::Object tmpp;
|
||||
tmpp.add("id", ejson::Number(1));
|
||||
tmpp.add("call", ejson::String("connect-service"));
|
||||
ejson::Array params;
|
||||
params.add(ejson::String(_serviceName));
|
||||
tmpp.add("param", params);
|
||||
m_interfaceClient->writeJson(tmpp);
|
||||
JUS_DEBUG("connect [STOP]");
|
||||
}
|
||||
|
||||
@ -97,12 +101,17 @@ bool jus::Service::GateWayAlive() {
|
||||
|
||||
void jus::Service::pingIsAlive() {
|
||||
if (std::chrono::steady_clock::now() - m_interfaceClient->getLastTimeSend() >= std::chrono::seconds(30)) {
|
||||
m_interfaceClient->write("{\"event\":\"IS-ALIVE\"}");
|
||||
/*
|
||||
ejson::Object tmpp;
|
||||
tmpp.add("event", ejson::String("IS-ALIVE"));
|
||||
m_interfaceClient->writeJson(tmpp);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void jus::Service::callJson(uint64_t _transactionId, const ejson::Object& _obj) {
|
||||
if (_obj.valueExist("event") == true) {
|
||||
void jus::Service::callBinary(uint32_t _transactionId, jus::Buffer& _obj) {
|
||||
if (_obj.getType() == jus::Buffer::typeMessage::event) {
|
||||
/*
|
||||
std::string event = _obj["event"].toString().get();
|
||||
if (event == "IS-ALIVE") {
|
||||
// Gateway just aswer a keep alive information ...
|
||||
@ -110,44 +119,39 @@ void jus::Service::callJson(uint64_t _transactionId, const ejson::Object& _obj)
|
||||
} else {
|
||||
JUS_ERROR("Unknow event: '" << event << "'");
|
||||
}
|
||||
*/
|
||||
JUS_ERROR("Unknow event: '...'");
|
||||
return;
|
||||
}
|
||||
ejson::Object answer;
|
||||
uint64_t clientId = _obj["client-id"].toNumber().getU64();
|
||||
if (_obj.valueExist("call") == true) {
|
||||
std::string call = _obj["call"].toString().get();
|
||||
ejson::Array params = _obj["param"].toArray();
|
||||
if (call[0] == '_') {
|
||||
if (call == "_new") {
|
||||
std::string userName = params[0].toString().get();
|
||||
std::string clientName = params[1].toString().get();
|
||||
std::vector<std::string> clientGroup = convertJsonTo<std::vector<std::string>>(params[2]);
|
||||
if (_obj.getType() == jus::Buffer::typeMessage::answer) {
|
||||
JUS_ERROR("Local Answer: '...'");
|
||||
return;
|
||||
}
|
||||
//if (_obj.getType() == jus::Buffer::typeMessage::event) {
|
||||
if (m_interfaceClient->getMode() == jus::connectionMode::modeBinary) {
|
||||
|
||||
} else if (m_interfaceClient->getMode() == jus::connectionMode::modeJson) {
|
||||
uint32_t clientId = _obj.getClientId();
|
||||
std::string callFunction = _obj.getCall();
|
||||
if (callFunction[0] == '_') {
|
||||
if (callFunction == "_new") {
|
||||
std::string userName = _obj.getParameter<std::string>(0);
|
||||
std::string clientName = _obj.getParameter<std::string>(1);
|
||||
std::vector<std::string> clientGroup = _obj.getParameter<std::vector<std::string>>(2);
|
||||
clientConnect(clientId, userName, clientName, clientGroup);
|
||||
} else if (call == "_delete") {
|
||||
} else if (callFunction == "_delete") {
|
||||
clientDisconnect(clientId);
|
||||
}
|
||||
// TODO : Do it better ...
|
||||
answer.add("id", ejson::Number(_transactionId));
|
||||
answer.add("client-id", ejson::Number(clientId));
|
||||
answer.add("return", ejson::Boolean(true));
|
||||
JUS_INFO("Answer: " << answer.generateHumanString());
|
||||
m_interfaceClient->write(answer.generateMachineString());
|
||||
m_interfaceClient->answerValue(_transactionId, true, clientId);
|
||||
return;
|
||||
} else if (isFunctionAuthorized(clientId, call) == true) {
|
||||
callJson2(_transactionId, clientId, call, params);
|
||||
} else if (isFunctionAuthorized(clientId, callFunction) == true) {
|
||||
callBinary2(_transactionId, clientId, callFunction, _obj);
|
||||
return;
|
||||
} else {
|
||||
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());
|
||||
m_interfaceClient->answerError(_transactionId, "NOT-AUTHORIZED-FUNCTION", "", clientId);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
JUS_ERROR("Not manage transfer mode ");
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
@ -69,8 +69,7 @@ namespace jus {
|
||||
void connect(const std::string& _serviceName, uint32_t _numberRetry = 1);
|
||||
void disconnect();
|
||||
private:
|
||||
void onClientData(std::string _value);
|
||||
std::string asyncRead();
|
||||
void onClientData(jus::Buffer& _value);
|
||||
public:
|
||||
void pingIsAlive();
|
||||
bool GateWayAlive();
|
||||
@ -86,8 +85,8 @@ namespace jus {
|
||||
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:
|
||||
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;
|
||||
void callBinary(uint32_t _transactionId, jus::Buffer& _obj);
|
||||
virtual void callBinary2(uint32_t _transactionId, uint64_t _clientId, const std::string& _call, jus::Buffer& _obj) = 0;
|
||||
std::vector<std::string> getExtention();
|
||||
public:
|
||||
// Add Local fuction (depend on this class)
|
||||
@ -116,6 +115,8 @@ namespace jus {
|
||||
JUS_INFO("Add function '" << _name << "' in local mode");
|
||||
m_listFunction.push_back(tmp);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
template<class JUS_TYPE_SERVICE, class JUS_USER_ACCESS>
|
||||
class ServiceType : public jus::Service {
|
||||
@ -208,15 +209,10 @@ namespace jus {
|
||||
}
|
||||
it->second.first->setGroups(_clientGroups);
|
||||
}
|
||||
void callJson2(uint64_t _transactionId, uint64_t _clientId, const std::string& _call, const ejson::Array& _params) {
|
||||
void callBinary2(uint32_t _transactionId, uint64_t _clientId, const std::string& _call, jus::Buffer& _obj) {
|
||||
auto it = m_interface.find(_clientId);
|
||||
if (it == m_interface.end()) {
|
||||
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());
|
||||
m_interfaceClient->answerError(_transactionId, "CLIENT-UNKNOW", "", _clientId);
|
||||
return;
|
||||
}
|
||||
for (auto &it2 : m_listFunction) {
|
||||
@ -229,19 +225,19 @@ namespace jus {
|
||||
switch (it2->getType()) {
|
||||
case jus::AbstractFunction::type::object: {
|
||||
JUS_TYPE_SERVICE* elem = it->second.second.get();
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)elem);
|
||||
it2->execute(m_interfaceClient, _transactionId, _clientId, _obj, (void*)elem);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::local: {
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)((RemoteProcessCall*)this));
|
||||
it2->execute(m_interfaceClient, _transactionId, _clientId, _obj, (void*)((RemoteProcessCall*)this));
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::service: {
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, (void*)this);
|
||||
it2->execute(m_interfaceClient, _transactionId, _clientId, _obj, (void*)this);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::global: {
|
||||
it2->executeJson(m_interfaceClient, _transactionId, _clientId, _params, nullptr);
|
||||
it2->execute(m_interfaceClient, _transactionId, _clientId, _obj, nullptr);
|
||||
return;
|
||||
}
|
||||
case jus::AbstractFunction::type::unknow:
|
||||
@ -249,14 +245,7 @@ namespace jus {
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
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());
|
||||
}
|
||||
m_interfaceClient->answerError(_transactionId, "FUNCTION-UNKNOW", "", _clientId);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -12,20 +12,20 @@ jus::TcpString::TcpString(enet::Tcp _connection) :
|
||||
m_connection(std::move(_connection)),
|
||||
m_thread(nullptr),
|
||||
m_observerElement(nullptr),
|
||||
m_observerRawElement(nullptr),
|
||||
m_threadAsync(nullptr) {
|
||||
m_threadRunning = false;
|
||||
m_threadAsyncRunning = false;
|
||||
m_interfaceMode = jus::connectionMode::modeJson;
|
||||
}
|
||||
|
||||
jus::TcpString::TcpString() :
|
||||
m_connection(),
|
||||
m_thread(nullptr),
|
||||
m_observerElement(nullptr),
|
||||
m_observerRawElement(nullptr),
|
||||
m_threadAsync(nullptr) {
|
||||
m_threadRunning = false;
|
||||
m_threadAsyncRunning = false;
|
||||
m_interfaceMode = jus::connectionMode::modeJson;
|
||||
}
|
||||
|
||||
void jus::TcpString::setInterface(enet::Tcp _connection) {
|
||||
@ -39,38 +39,14 @@ jus::TcpString::~TcpString() {
|
||||
void jus::TcpString::setInterfaceName(const std::string& _name) {
|
||||
ethread::setName(*m_thread, "Tcp-" + _name);
|
||||
}
|
||||
// TODO : Do it better :
|
||||
|
||||
void jus::TcpString::threadCallback() {
|
||||
ethread::setName("TcpString-input");
|
||||
// get datas:
|
||||
while ( m_threadRunning == true
|
||||
&& m_connection.getConnectionStatus() == enet::Tcp::status::link) {
|
||||
// READ section data:
|
||||
if (m_observerElement != nullptr) {
|
||||
JUS_PRINT("Call String ...");
|
||||
std::string data = std::move(read());
|
||||
JUS_PRINT("Receive data: '" << data << "'");
|
||||
if (data.size() != 0) {
|
||||
m_lastReceive = std::chrono::steady_clock::now();
|
||||
JUS_PRINT(" Call function ... 1");
|
||||
if (m_observerElement != nullptr) {
|
||||
m_observerElement(std::move(data));
|
||||
} else if (m_observerRawElement != nullptr) {
|
||||
jus::Buffer dataRaw;
|
||||
dataRaw.composeWith(data);
|
||||
m_observerRawElement(dataRaw);
|
||||
} else {
|
||||
JUS_ERROR("Lose DATA ...");
|
||||
}
|
||||
JUS_PRINT(" Call function ... 1 (done)");
|
||||
}
|
||||
} else if (m_observerRawElement != nullptr) {
|
||||
JUS_PRINT("Call Raw ...");
|
||||
jus::Buffer data = readRaw();
|
||||
JUS_PRINT(" Call function ... 2");
|
||||
m_observerRawElement(data);
|
||||
JUS_PRINT(" Call function ... 2 (done)");
|
||||
}
|
||||
read();
|
||||
}
|
||||
m_threadRunning = false;
|
||||
JUS_DEBUG("End of thread");
|
||||
@ -136,33 +112,30 @@ void jus::TcpString::disconnect(bool _inThreadStop){
|
||||
JUS_DEBUG("disconnect [STOP]");
|
||||
}
|
||||
|
||||
int32_t jus::TcpString::write(const std::string& _data) {
|
||||
int32_t jus::TcpString::writeJson(ejson::Object& _data) {
|
||||
JUS_DEBUG("Send JSON '" << _data.generateHumanString() << "'");
|
||||
if (m_threadRunning == false) {
|
||||
return -2;
|
||||
}
|
||||
if (_data.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t size = _data.size();
|
||||
m_lastSend = std::chrono::steady_clock::now();
|
||||
m_connection.write(&size, 4);
|
||||
return m_connection.write(_data.c_str(), _data.size());
|
||||
m_connection.write("J", 1);
|
||||
std::string tmpData = _data.generateMachineString();
|
||||
uint32_t dataSize = tmpData.size();
|
||||
m_connection.write(&dataSize, sizeof(uint32_t));
|
||||
m_connection.write(&tmpData[0], tmpData.size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t jus::TcpString::writeBinary(jus::Buffer& _data) {
|
||||
_data.prepare();
|
||||
JUS_DEBUG("Send BINARY '" << _data.generateHumanString() << "'");
|
||||
JUS_DEBUG("Send BINARY '" << _data.toJson().generateHumanString() << "'");
|
||||
if (m_threadRunning == false) {
|
||||
return -2;
|
||||
}
|
||||
/*
|
||||
if (_data.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
//uint32_t size = _data.size();
|
||||
m_lastSend = std::chrono::steady_clock::now();
|
||||
m_connection.write("B", 1);
|
||||
const uint8_t* data = nullptr;
|
||||
uint32_t dataSize = 0;
|
||||
m_lastSend = std::chrono::steady_clock::now();
|
||||
data = _data.getHeader();
|
||||
dataSize = _data.getHeaderSize();
|
||||
m_connection.write(data, dataSize);
|
||||
@ -175,84 +148,92 @@ int32_t jus::TcpString::writeBinary(jus::Buffer& _data) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string jus::TcpString::read() {
|
||||
void jus::TcpString::read() {
|
||||
JUS_VERBOSE("Read [START]");
|
||||
if (m_threadRunning == false) {
|
||||
JUS_DEBUG("Read [END] Disconected");
|
||||
return "";
|
||||
return;
|
||||
}
|
||||
// TODO : Do it better with a correct way to check data size ...
|
||||
JUS_VERBOSE("Read [START]");
|
||||
std::string out;
|
||||
uint32_t size = 0;
|
||||
int32_t len = m_connection.read(&size, 4);
|
||||
if (len != 4) {
|
||||
JUS_ERROR("Protocol error occured ...");
|
||||
uint8_t type = 0;
|
||||
int32_t len = m_connection.read(&type, 1);
|
||||
if (len == 0) {
|
||||
JUS_ERROR("Protocol error occured ==> No datas ...");
|
||||
} else {
|
||||
if (size == -1) {
|
||||
JUS_WARNING("Remote close connection");
|
||||
m_threadRunning = false;
|
||||
//m_connection.unlink();
|
||||
} else {
|
||||
int64_t offset = 0;
|
||||
out.resize(size);
|
||||
while (offset != size) {
|
||||
len = m_connection.read(&out[offset], size-offset);
|
||||
offset += len;
|
||||
if (len == 0) {
|
||||
JUS_WARNING("Read No data");
|
||||
//break;
|
||||
if (type == 'B') { // binary
|
||||
// Binary mode ... start with the lenght of the stream
|
||||
JUS_VERBOSE("Read Binary [START]");
|
||||
uint32_t size = 0;
|
||||
len = m_connection.read(&size, 4);
|
||||
if (len != 4) {
|
||||
JUS_ERROR("Protocol error occured ...");
|
||||
} else {
|
||||
if (size == -1) {
|
||||
JUS_WARNING("Remote close connection");
|
||||
m_threadRunning = false;
|
||||
//m_connection.unlink();
|
||||
} else {
|
||||
int64_t offset = 0;
|
||||
m_buffer.resize(size);
|
||||
while (offset != size) {
|
||||
len = m_connection.read(&m_buffer[offset], size-offset);
|
||||
offset += len;
|
||||
if (len == 0) {
|
||||
JUS_WARNING("Read No data");
|
||||
}
|
||||
}
|
||||
if (m_observerElement != nullptr) {
|
||||
jus::Buffer dataRaw;
|
||||
dataRaw.composeWith(m_buffer);
|
||||
JUS_VERBOSE("Receive Binary :" << dataRaw.toJson().generateHumanString());
|
||||
m_observerElement(dataRaw);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (size != offset) {
|
||||
JUS_ERROR("Protocol error occured .2. ==> concat (offset=" << offset << " size=" << size);
|
||||
}
|
||||
*/
|
||||
}
|
||||
JUS_VERBOSE("ReadRaw [STOP]");
|
||||
} else if ( type == 'X' // XML
|
||||
|| type == 'J' // JSON
|
||||
) {
|
||||
JUS_VERBOSE("Read sized String [START]");
|
||||
// XML/JSON mode ... start with the lenght of the stream
|
||||
std::string out;
|
||||
uint32_t size = 0;
|
||||
len = m_connection.read(&size, 4);
|
||||
if (len != 4) {
|
||||
JUS_ERROR("Protocol error occured ...");
|
||||
} else {
|
||||
if (size == -1) {
|
||||
JUS_WARNING("Remote close connection");
|
||||
m_threadRunning = false;
|
||||
//m_connection.unlink();
|
||||
} else {
|
||||
int64_t offset = 0;
|
||||
out.resize(size);
|
||||
while (offset != size) {
|
||||
len = m_connection.read(&out[offset], size-offset);
|
||||
offset += len;
|
||||
if (len == 0) {
|
||||
JUS_WARNING("Read No data");
|
||||
}
|
||||
}
|
||||
if (m_observerElement != nullptr) {
|
||||
JUS_VERBOSE("Receive String :" << out);
|
||||
jus::Buffer dataRaw;
|
||||
dataRaw.composeWith(out);
|
||||
m_observerElement(dataRaw);
|
||||
}
|
||||
}
|
||||
}
|
||||
JUS_VERBOSE("Read sized String [STOP]");
|
||||
} else if (type == '{') {
|
||||
// JSON Raw mode ... Finish with a \0
|
||||
// TODO: m_dataBuffer
|
||||
} else if (type == '<') {
|
||||
// XML Raw mode ... Finish with a \0
|
||||
// TODO : m_dataBuffer
|
||||
}
|
||||
}
|
||||
JUS_VERBOSE("Read [STOP]");
|
||||
return out;
|
||||
}
|
||||
|
||||
jus::Buffer jus::TcpString::readRaw() {
|
||||
jus::Buffer out;
|
||||
JUS_VERBOSE("ReadRaw [START]");
|
||||
if (m_threadRunning == false) {
|
||||
JUS_DEBUG("Read [END] Disconected");
|
||||
return out;
|
||||
}
|
||||
JUS_VERBOSE("ReadRaw [START]");
|
||||
uint32_t size = 0;
|
||||
int32_t len = m_connection.read(&size, 4);
|
||||
if (len != 4) {
|
||||
JUS_ERROR("Protocol error occured ...");
|
||||
} else {
|
||||
if (size == -1) {
|
||||
JUS_WARNING("Remote close connection");
|
||||
m_threadRunning = false;
|
||||
//m_connection.unlink();
|
||||
} else {
|
||||
int64_t offset = 0;
|
||||
m_buffer.resize(size);
|
||||
while (offset != size) {
|
||||
len = m_connection.read(&m_buffer[offset], size-offset);
|
||||
offset += len;
|
||||
if (len == 0) {
|
||||
JUS_WARNING("Read No data");
|
||||
//break;
|
||||
}
|
||||
/*
|
||||
else if (size != offset) {
|
||||
JUS_ERROR("Protocol error occured .2. ==> concat (offset=" << offset << " size=" << size);
|
||||
}
|
||||
*/
|
||||
}
|
||||
out.composeWith(m_buffer);
|
||||
}
|
||||
}
|
||||
JUS_VERBOSE("ReadRaw [STOP]");
|
||||
return out;
|
||||
}
|
||||
|
||||
void jus::TcpString::threadAsyncCallback() {
|
||||
@ -280,3 +261,51 @@ void jus::TcpString::threadAsyncCallback() {
|
||||
JUS_DEBUG("End of thread");
|
||||
}
|
||||
|
||||
|
||||
void jus::TcpString::answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorHelp, uint32_t _clientId) {
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
ejson::Object answer;
|
||||
answer.add("error", ejson::String(_errorValue));
|
||||
answer.add("id", ejson::Number(_clientTransactionId));
|
||||
if (_clientId != 0) {
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
}
|
||||
answer.add("error-help", ejson::String(_errorHelp));
|
||||
writeJson(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
jus::Buffer answer;
|
||||
answer.setType(jus::Buffer::typeMessage::answer);
|
||||
answer.setTransactionId(_clientTransactionId);
|
||||
answer.setClientId(_clientId);
|
||||
answer.addError(_errorValue, _errorHelp);
|
||||
writeBinary(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("TODO ... ");
|
||||
} else {
|
||||
JUS_ERROR("wrong type of communication");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jus::TcpString::answerVoid(uint64_t _clientTransactionId, uint32_t _clientId) {
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_clientTransactionId));
|
||||
if (_clientId != 0) {
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
}
|
||||
answer.add("return", ejson::Null());
|
||||
writeJson(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
jus::Buffer answer;
|
||||
answer.setType(jus::Buffer::typeMessage::answer);
|
||||
answer.setTransactionId(_clientTransactionId);
|
||||
answer.setClientId(_clientId);
|
||||
answer.addParameter();
|
||||
writeBinary(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("TODO ... ");
|
||||
} else {
|
||||
JUS_ERROR("wrong type of communication");
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@
|
||||
#include <enet/Tcp.h>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <jus/connectionMode.h>
|
||||
#include <jus/AbstractFunction.h>
|
||||
|
||||
namespace jus {
|
||||
class TcpString : public eproperty::Interface {
|
||||
@ -17,13 +19,22 @@ namespace jus {
|
||||
enet::Tcp m_connection;
|
||||
std::thread* m_thread;
|
||||
bool m_threadRunning;
|
||||
protected:
|
||||
enum jus::connectionMode m_interfaceMode;
|
||||
public:
|
||||
enum jus::connectionMode getMode() {
|
||||
return m_interfaceMode;
|
||||
}
|
||||
void setMode(enum jus::connectionMode _mode) {
|
||||
m_interfaceMode = _mode;
|
||||
}
|
||||
std::vector<uint8_t> m_buffer;
|
||||
std::vector<uint8_t> m_temporaryBuffer;
|
||||
std::chrono::steady_clock::time_point m_lastReceive;
|
||||
std::chrono::steady_clock::time_point m_lastSend;
|
||||
public:
|
||||
using Observer = std::function<void(std::string)>; //!< Define an Observer: function pointer
|
||||
using ObserverRaw = std::function<void(jus::Buffer&)>; //!< Define an Observer: function pointer
|
||||
using Observer = std::function<void(jus::Buffer&)>; //!< Define an Observer: function pointer
|
||||
Observer m_observerElement;
|
||||
ObserverRaw m_observerRawElement;
|
||||
/**
|
||||
* @brief Connect an function member on the signal with the shared_ptr object.
|
||||
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
|
||||
@ -31,23 +42,11 @@ namespace jus {
|
||||
* @param[in] _args Argument optinnal the user want to add.
|
||||
*/
|
||||
template<class CLASS_TYPE>
|
||||
void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(std::string)) {
|
||||
m_observerElement = [=](std::string _value){
|
||||
(*_class.*_func)(std::move(_value));
|
||||
};
|
||||
}
|
||||
void connectClean() {
|
||||
m_observerElement = nullptr;
|
||||
}
|
||||
template<class CLASS_TYPE>
|
||||
void connectRaw(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(jus::Buffer&)) {
|
||||
m_observerRawElement = [=](jus::Buffer& _value){
|
||||
void connect(CLASS_TYPE* _class, void (CLASS_TYPE::*_func)(jus::Buffer&)) {
|
||||
m_observerElement = [=](jus::Buffer& _value){
|
||||
(*_class.*_func)(_value);
|
||||
};
|
||||
}
|
||||
void connectCleanRaw() {
|
||||
m_observerRawElement = nullptr;
|
||||
}
|
||||
public:
|
||||
TcpString();
|
||||
TcpString(enet::Tcp _connection);
|
||||
@ -57,13 +56,12 @@ namespace jus {
|
||||
void disconnect(bool _inThreadStop = false);
|
||||
bool isActive() const;
|
||||
void setInterfaceName(const std::string& _name);
|
||||
int32_t write(const std::string& _data);
|
||||
int32_t writeJson(ejson::Object& _data);
|
||||
int32_t writeBinary(jus::Buffer& _data);
|
||||
std::string asyncRead();
|
||||
private:
|
||||
std::string read();
|
||||
void read();
|
||||
jus::Buffer readRaw();
|
||||
std::vector<uint8_t> m_buffer;
|
||||
private:
|
||||
void threadCallback();
|
||||
public:
|
||||
@ -86,6 +84,39 @@ namespace jus {
|
||||
std::unique_lock<std::mutex> lock(m_threadAsyncMutex);
|
||||
m_threadAsyncList.push_back(_elem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
|
||||
template<class JUS_ARG>
|
||||
void answerValue(uint64_t _clientTransactionId, JUS_ARG _value, uint32_t _clientId=0) {
|
||||
if (m_interfaceMode == jus::connectionMode::modeJson) {
|
||||
ejson::Object answer;
|
||||
answer.add("id", ejson::Number(_clientTransactionId));
|
||||
if (_clientId != 0) {
|
||||
answer.add("client-id", ejson::Number(_clientId));
|
||||
}
|
||||
std::vector<jus::ActionAsyncClient> asyncAction;
|
||||
answer.add("return", jus::convertToJson(asyncAction, -1, _value));
|
||||
if (asyncAction.size() != 0) {
|
||||
JUS_ERROR("ASYNC datas ... TODO ///");
|
||||
}
|
||||
writeJson(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeBinary) {
|
||||
jus::Buffer answer;
|
||||
answer.setType(jus::Buffer::typeMessage::answer);
|
||||
answer.setTransactionId(_clientTransactionId);
|
||||
answer.setClientId(_clientId);
|
||||
answer.addAnswer(_value);
|
||||
writeBinary(answer);
|
||||
} else if (m_interfaceMode == jus::connectionMode::modeXml) {
|
||||
JUS_ERROR("TODO ... ");
|
||||
} else {
|
||||
JUS_ERROR("wrong type of communication");
|
||||
}
|
||||
}
|
||||
void answerVoid(uint64_t _clientTransactionId, uint32_t _clientId=0);
|
||||
void answerError(uint64_t _clientTransactionId, const std::string& _errorValue, const std::string& _errorComment="", uint32_t _clientId=0);
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user