[DEV] extract rpc and better interaction between client and service

This commit is contained in:
Edouard DUPIN 2016-05-22 22:40:42 +02:00
parent 2c8b62b712
commit a01f8e3e8d
23 changed files with 979 additions and 493 deletions

145
jus/AbstractFunction.cpp Normal file
View File

@ -0,0 +1,145 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <jus/AbstractFunction.h>
#include <jus/debug.h>
template<> bool convertJsonTo<bool>(const ejson::Value& _value) {
return _value.toBoolean().get();
}
template<> float convertJsonTo<float>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> double convertJsonTo<double>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> int64_t convertJsonTo<int64_t>(const ejson::Value& _value) {
return int64_t(_value.toNumber().get());
}
template<> int32_t convertJsonTo<int32_t>(const ejson::Value& _value) {
//_value.display();
return int32_t(_value.toNumber().get());
}
template<> int16_t convertJsonTo<int16_t>(const ejson::Value& _value) {
return int16_t(_value.toNumber().get());
}
template<> int8_t convertJsonTo<int8_t>(const ejson::Value& _value) {
return int8_t(_value.toNumber().get());
}
template<> uint64_t convertJsonTo<uint64_t>(const ejson::Value& _value) {
return uint64_t(_value.toNumber().get());
}
template<> uint32_t convertJsonTo<uint32_t>(const ejson::Value& _value) {
return uint32_t(_value.toNumber().get());
}
template<> uint16_t convertJsonTo<uint16_t>(const ejson::Value& _value) {
return uint16_t(_value.toNumber().get());
}
template<> uint8_t convertJsonTo<uint8_t>(const ejson::Value& _value) {
return uint8_t(_value.toNumber().get());
}
template<> std::string convertJsonTo<std::string>(const ejson::Value& _value) {
//_value.display();
return _value.toString().get();
}
template<> ejson::Value convertToJson<bool>(const bool& _value) {
return ejson::Boolean(_value);
}
template<> ejson::Value convertToJson<float>(const float& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<double>(const double& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int64_t>(const int64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int32_t>(const int32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int16_t>(const int16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int8_t>(const int8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint64_t>(const uint64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint32_t>(const uint32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint16_t>(const uint16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint8_t>(const uint8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<std::string>(const std::string& _value) {
return ejson::String(_value);
}
template<> bool convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value);
}
template<> float convertStringTo<float>(const std::string& _value) {
return etk::string_to_float(_value);
}
template<> double convertStringTo<double>(const std::string& _value) {
return etk::string_to_double(_value);
}
template<> int64_t convertStringTo<int64_t>(const std::string& _value) {
return etk::string_to_int64_t(_value);
}
template<> int32_t convertStringTo<int32_t>(const std::string& _value) {
return etk::string_to_int32_t(_value);
}
template<> int16_t convertStringTo<int16_t>(const std::string& _value) {
return etk::string_to_int16_t(_value);
}
template<> int8_t convertStringTo<int8_t>(const std::string& _value) {
return etk::string_to_int8_t(_value);
}
template<> uint64_t convertStringTo<uint64_t>(const std::string& _value) {
return etk::string_to_uint64_t(_value);
}
template<> uint32_t convertStringTo<uint32_t>(const std::string& _value) {
return etk::string_to_uint32_t(_value);
}
template<> uint16_t convertStringTo<uint16_t>(const std::string& _value) {
return etk::string_to_uint16_t(_value);
}
template<> uint8_t convertStringTo<uint8_t>(const std::string& _value) {
return etk::string_to_uint8_t(_value);
}
template<> std::string convertStringTo<std::string>(const std::string& _value) {
return _value;
}
bool AbstractFunction::checkCompatibility(const ParamType& _type, const ejson::Value& _params) {
if (createType<bool>() == _type) {
return _params.isBoolean();
}
if ( createType<int64_t>() == _type
|| createType<int32_t>() == _type
|| createType<int16_t>() == _type
|| createType<int8_t>() == _type
|| createType<uint64_t>() == _type
|| createType<uint32_t>() == _type
|| createType<uint16_t>() == _type
|| createType<uint8_t>() == _type
|| createType<float>() == _type
|| createType<double>() == _type) {
return _params.isNumber();
}
if (createType<std::string>() == _type) {
return _params.isString();
}
return false;
}
bool AbstractFunction::checkCompatibility(const ParamType& _type, const std::string& _params) {
return false;
}

56
jus/AbstractFunction.h Normal file
View File

@ -0,0 +1,56 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @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>
class AbstractFunction {
protected:
const std::string m_name;
public:
const std::string& getName() const {
return m_name;
}
protected:
const std::string m_description;
public:
const std::string& getDescription() const {
return m_description;
}
protected:
AbstractFunction(const std::string& _name,
const std::string& _desc):
m_name(_name),
m_description(_desc) {
}
public:
virtual ~AbstractFunction() {};
bool checkCompatibility(const ParamType& _type, const ejson::Value& _params);
bool checkCompatibility(const ParamType& _type, const std::string& _params);
public:
virtual std::string getPrototype() const = 0;
virtual ejson::Value executeJson(const ejson::Array& _params, void* _class=nullptr) = 0;
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
};
template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value);
template<class JUS_TYPE>
JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
/*
template <class, class...>
class TypeList;
*/

View File

View File

@ -0,0 +1,175 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @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/AbstractFunction.h>
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#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++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
(*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
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 "";
}
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
class AbstractFunctionTypeClass: public AbstractFunction {
protected:
static const ParamType m_returnType;
static const ParamType m_paramType[sizeof...(JUS_TYPES)];
public:
using functionType = JUS_RETURN (JUS_CLASS_TYPE::*)(JUS_TYPES...);
functionType m_function;
AbstractFunctionTypeClass(const std::string& _name, const std::string& _desc, functionType _fptr):
AbstractFunction(_name, _desc),
m_function(_fptr) {
}
std::string getPrototype() const override {
std::string ret;
ret += m_returnType.getName();
ret += " ";
ret += m_name;
ret += "(";
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
}
ret += m_paramType[iii].getName();
}
ret += ");";
return ret;
}
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
std::string help = "request ";
help += etk::to_string(_params.size());
help += " parameters and need ";
help += etk::to_string(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
return out;
}
}
// execute cmd:
ejson::Value retVal = executeClassCallJson(tmpClass, m_function, _params);
out.add("return", retVal);
return out;
}
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 = executeClassCallString(tmpClass, m_function, _params);
return out;
}
};
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, class JUS_CLASS_TYPE, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionClass(const std::string& _name, const std::string& _desc, JUS_RETURN (JUS_CLASS_TYPE::*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>(_name, _desc, _fffp);
}

View File

View File

@ -0,0 +1,173 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @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/AbstractFunction.h>
template <class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeCallJson(JUS_RETURN (*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class... JUS_TYPES>
ejson::Value executeCallJson(void (*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
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((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(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((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class... JUS_TYPES>
class AbstractFunctionTypeDirect: public AbstractFunction {
protected:
static const ParamType m_returnType;
static const ParamType m_paramType[sizeof...(JUS_TYPES)];
public:
using functionType = JUS_RETURN (*)(JUS_TYPES...);
functionType m_function;
AbstractFunctionTypeDirect(const std::string& _name, const std::string& _desc, functionType _fptr):
AbstractFunction(_name, _desc),
m_function(_fptr) {
}
std::string getPrototype() const override {
std::string ret;
ret += m_returnType.getName();
ret += " ";
ret += m_name;
ret += "(";
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
}
ret += m_paramType[iii].getName();
}
ret += ");";
return ret;
}
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
std::string help = "request ";
help += etk::to_string(_params.size());
help += " parameters and need ";
help += etk::to_string(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
return out;
}
}
// execute cmd:
ejson::Value retVal = executeCallJson(m_function, _params);
out.add("return", retVal);
return out;
}
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 = executeCallString(m_function, _params);
return out;
}
};
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionDirect(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>(_name, _desc, _fffp);
}

View File

@ -68,10 +68,13 @@ void jus::Client::disconnect(){
JUS_DEBUG("disconnect [STOP]"); JUS_DEBUG("disconnect [STOP]");
} }
ejson::Object jus::Client::createBaseCall(const std::string& _functionName) { ejson::Object jus::Client::createBaseCall(const std::string& _service, const std::string& _functionName) {
ejson::Object obj; ejson::Object obj;
if (_service.size() != 0) {
obj.add("service", ejson::String(_service));
}
obj.add("call", ejson::String(_functionName)); obj.add("call", ejson::String(_functionName));
obj.add("transaction-id", ejson::Number(m_id++)); obj.add("id", ejson::Number(m_id++));
obj.add("param", ejson::Array()); obj.add("param", ejson::Array());
return obj; return obj;
} }

View File

@ -29,7 +29,7 @@ namespace jus {
void onClientData(const std::string& _value); void onClientData(const std::string& _value);
std::string asyncRead(); std::string asyncRead();
ejson::Object callJson(const ejson::Object& _obj); ejson::Object callJson(const ejson::Object& _obj);
ejson::Object createBaseCall(const std::string& _functionName); ejson::Object createBaseCall( const std::string& _service, const std::string& _functionName);
void createParam(ejson::Object& _obj) { void createParam(ejson::Object& _obj) {
// Finish recursive parse ... // Finish recursive parse ...
} }
@ -125,8 +125,8 @@ namespace jus {
} }
public: public:
template<class... _ARGS> template<class... _ARGS>
void call(const std::string& _functionName, _ARGS&&... _args) { void call(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -134,8 +134,8 @@ namespace jus {
} }
} }
template<class... _ARGS> template<class... _ARGS>
int32_t call_i(const std::string& _functionName, _ARGS&&... _args) { int32_t call_i(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -153,8 +153,8 @@ namespace jus {
return int32_t(val.toNumber().get()); return int32_t(val.toNumber().get());
} }
template<class... _ARGS> template<class... _ARGS>
double call_d(const std::string& _functionName, _ARGS&&... _args) { double call_d(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -172,8 +172,8 @@ namespace jus {
return val.toNumber().get(); return val.toNumber().get();
} }
template<class... _ARGS> template<class... _ARGS>
std::string call_s(const std::string& _functionName, _ARGS&&... _args) { std::string call_s(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -191,8 +191,8 @@ namespace jus {
return val.toString().get(); return val.toString().get();
} }
template<class... _ARGS> template<class... _ARGS>
bool call_b(const std::string& _functionName, _ARGS&&... _args) { bool call_b(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -210,8 +210,8 @@ namespace jus {
return val.toBoolean().get(); return val.toBoolean().get();
} }
template<class... _ARGS> template<class... _ARGS>
std::vector<int32_t> call_vi(const std::string& _functionName, _ARGS&&... _args) { std::vector<int32_t> call_vi(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -241,8 +241,8 @@ namespace jus {
return out; return out;
} }
template<class... _ARGS> template<class... _ARGS>
std::vector<double> call_vd(const std::string& _functionName, _ARGS&&... _args) { std::vector<double> call_vd(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -272,8 +272,8 @@ namespace jus {
return out; return out;
} }
template<class... _ARGS> template<class... _ARGS>
std::vector<std::string> call_vs(const std::string& _functionName, _ARGS&&... _args) { std::vector<std::string> call_vs(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {
@ -303,8 +303,8 @@ namespace jus {
return out; return out;
} }
template<class... _ARGS> template<class... _ARGS>
std::vector<bool> call_vb(const std::string& _functionName, _ARGS&&... _args) { std::vector<bool> call_vb(const std::string& _service, const std::string& _functionName, _ARGS&&... _args) {
ejson::Object callElem = createBaseCall(_functionName); ejson::Object callElem = createBaseCall(_service, _functionName);
createParam(callElem, std::forward<_ARGS>(_args)...); createParam(callElem, std::forward<_ARGS>(_args)...);
ejson::Object obj = callJson(callElem); ejson::Object obj = callJson(callElem);
if (obj.valueExist("error") == true) { if (obj.valueExist("error") == true) {

View File

@ -10,6 +10,7 @@
jus::GateWay::GateWay() : jus::GateWay::GateWay() :
m_clientUID(1),
propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &jus::GateWay::onPropertyChangeClientIp), propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &jus::GateWay::onPropertyChangeClientIp),
propertyClientPort(this, "client-port", 1983, "Port to listen client", &jus::GateWay::onPropertyChangeClientPort), propertyClientPort(this, "client-port", 1983, "Port to listen client", &jus::GateWay::onPropertyChangeClientPort),
propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &jus::GateWay::onPropertyChangeClientMax), propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &jus::GateWay::onPropertyChangeClientMax),
@ -24,17 +25,39 @@ jus::GateWay::~GateWay() {
} }
void jus::GateWay::start() { void jus::GateWay::start() {
m_clientWaiting = std::make_shared<jus::GateWayClient>(); m_clientWaiting = std::make_shared<jus::GateWayClient>(this);
m_clientConnected = m_clientWaiting->signalIsConnected.connect(this, &jus::GateWay::onClientConnect); m_clientConnected = m_clientWaiting->signalIsConnected.connect(this, &jus::GateWay::onClientConnect);
m_clientWaiting->start(*propertyClientIp, *propertyClientPort); m_clientWaiting->start(*propertyClientIp, *propertyClientPort, m_clientUID++);
m_serviceWaiting = std::make_shared<jus::GateWayService>(this);
m_serviceConnected = m_serviceWaiting->signalIsConnected.connect(this, &jus::GateWay::onServiceConnect);
m_serviceWaiting->start(*propertyServiceIp, *propertyServicePort);
} }
void jus::GateWay::stop() { void jus::GateWay::stop() {
} }
ememory::SharedPtr<jus::GateWayService> jus::GateWay::get(const std::string& _serviceName) {
for (auto &it : m_serviceList) {
if (it == nullptr) {
continue;
}
if (it->getName() != _serviceName) {
continue;
}
return it;
}
// TODO : Remove this ...
return m_serviceWaiting;
return nullptr;
}
void jus::GateWay::onClientConnect(const bool& _value) { void jus::GateWay::onClientConnect(const bool& _value) {
JUS_TODO("lklklk: " << _value); JUS_TODO("Client connection: " << _value);
}
void jus::GateWay::onServiceConnect(const bool& _value) {
JUS_TODO("Service connection: " << _value);
} }
void jus::GateWay::onPropertyChangeClientIp() { void jus::GateWay::onPropertyChangeClientIp() {

View File

@ -9,12 +9,16 @@
namespace jus { namespace jus {
class GateWay : public eproperty::Interface { class GateWay : public eproperty::Interface {
private:
size_t m_clientUID;
private: private:
std::vector<ememory::SharedPtr<jus::GateWayService>> m_serviceList; //!< List of all service availlable with their specific connection interface std::vector<ememory::SharedPtr<jus::GateWayService>> m_serviceList; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<jus::GateWayClient>> m_clientList; //!< List of all Client interface with their own connection std::vector<ememory::SharedPtr<jus::GateWayClient>> m_clientList; //!< List of all Client interface with their own connection
//TODO: std::vector<jus::GateWayServer> m_ServerList; //!< List of all Server connected to this gateway //TODO: std::vector<jus::GateWayServer> m_ServerList; //!< List of all Server connected to this gateway
ememory::SharedPtr<jus::GateWayClient> m_clientWaiting; ememory::SharedPtr<jus::GateWayClient> m_clientWaiting;
esignal::Connection m_clientConnected; esignal::Connection m_clientConnected;
ememory::SharedPtr<jus::GateWayService> m_serviceWaiting;
esignal::Connection m_serviceConnected;
public: public:
eproperty::Value<std::string> propertyClientIp; eproperty::Value<std::string> propertyClientIp;
eproperty::Value<uint16_t> propertyClientPort; eproperty::Value<uint16_t> propertyClientPort;
@ -27,6 +31,7 @@ namespace jus {
virtual ~GateWay(); virtual ~GateWay();
void start(); void start();
void stop(); void stop();
ememory::SharedPtr<jus::GateWayService> get(const std::string& _serviceName);
private: private:
void onPropertyChangeClientIp(); void onPropertyChangeClientIp();
void onPropertyChangeClientPort(); void onPropertyChangeClientPort();
@ -35,6 +40,7 @@ namespace jus {
void onPropertyChangeServicePort(); void onPropertyChangeServicePort();
void onPropertyChangeServiceMax(); void onPropertyChangeServiceMax();
void onClientConnect(const bool& _value); void onClientConnect(const bool& _value);
void onServiceConnect(const bool& _value);
}; };
} }

View File

@ -7,8 +7,12 @@
#include <jus/debug.h> #include <jus/debug.h>
#include <jus/GateWayClient.h> #include <jus/GateWayClient.h>
#include <ejson/ejson.h> #include <ejson/ejson.h>
#include <jus/GateWay.h>
#include <unistd.h>
jus::GateWayClient::GateWayClient() { jus::GateWayClient::GateWayClient(jus::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface),
m_returnValueOk(false) {
} }
@ -16,11 +20,13 @@ jus::GateWayClient::~GateWayClient() {
} }
void jus::GateWayClient::start(const std::string& _ip, uint16_t _port) { void jus::GateWayClient::start(const std::string& _ip, uint16_t _port, size_t _uid) {
m_interfaceClient.propertyIp.set(_ip); m_interfaceClient.propertyIp.set(_ip);
m_interfaceClient.propertyPort.set(_port); m_interfaceClient.propertyPort.set(_port);
m_uid = _uid;
m_interfaceClient.propertyServer.set(true); m_interfaceClient.propertyServer.set(true);
m_interfaceClient.connect(); m_interfaceClient.connect(true);
m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid));
m_dataCallback = m_interfaceClient.signalData.connect(this, &jus::GateWayClient::onClientData); m_dataCallback = m_interfaceClient.signalData.connect(this, &jus::GateWayClient::onClientData);
} }
@ -42,7 +48,7 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
std::string call = data["call"].toString().get(); std::string call = data["call"].toString().get();
ejson::Object answer; ejson::Object answer;
answer.add("from-service", ejson::String("ServiceManager")); answer.add("from-service", ejson::String("ServiceManager"));
answer.add("transaction-id", data["transaction-id"]); answer.add("id", data["id"]);
if (call == "getServiceCount") { if (call == "getServiceCount") {
// TODO : Do it better: // TODO : Do it better:
answer.add("return", ejson::Number(2)); answer.add("return", ejson::Number(2));
@ -53,6 +59,21 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
answer.add("return", listService); answer.add("return", listService);
} else if (call == "getServiceInformation") { } else if (call == "getServiceInformation") {
} else if (call == "link") {
// first param :
std::string serviceName = data["param"].toArray()[0].toString().get();
// TODO : check if already connected ...
//m_listConnectedService
// TODO : check if we have authorisation to connect service
ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName);
if (srv != nullptr) {
m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true));
} else {
answer.add("return", ejson::Boolean(false));
}
} else if (call == "unlink") {
answer.add("return", ejson::Boolean(false));
} else { } else {
JUS_ERROR("Function does not exist ... '" << call << "'"); JUS_ERROR("Function does not exist ... '" << call << "'");
answer.add("error", ejson::String("CALL-UNEXISTING")); answer.add("error", ejson::String("CALL-UNEXISTING"));
@ -64,7 +85,28 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
std::string call = data["call"].toString().get(); std::string call = data["call"].toString().get();
} else { } else {
JUS_TODO("mmmmmmmmmmm: " << _value); for (auto &it : m_listConnectedService) {
if (it == nullptr) {
continue;
}
if (it->getName() != service) {
continue;
}
it->SendData(m_uid, data);
while (m_returnValueOk == false) {
JUS_DEBUG("wait Return Value");
usleep(20000);
}
std::string valueReturn = m_returnMessage.generate();
JUS_DEBUG("answer: " << valueReturn);
m_interfaceClient.write(valueReturn);
m_returnValueOk = false;
break;
}
} }
} }
void jus::GateWayClient::returnMessage(ejson::Object _data) {
m_returnMessage = _data;
m_returnValueOk = true;
}

View File

@ -8,19 +8,28 @@
#include <jus/TcpString.h> #include <jus/TcpString.h>
#include <ememory/memory.h> #include <ememory/memory.h>
#include <esignal/Signal.h> #include <esignal/Signal.h>
#include <jus/GateWayService.h>
namespace jus { namespace jus {
class GateWay;
class GateWayClient { class GateWayClient {
private:
jus::GateWay* m_gatewayInterface;
public: public:
jus::TcpString m_interfaceClient; jus::TcpString m_interfaceClient;
esignal::Signal<bool> signalIsConnected; esignal::Signal<bool> signalIsConnected;
esignal::Connection m_dataCallback; esignal::Connection m_dataCallback;
bool m_returnValueOk;
ejson::Object m_returnMessage;
std::vector<ememory::SharedPtr<jus::GateWayService>> m_listConnectedService;
size_t m_uid;
public: public:
GateWayClient(); GateWayClient(jus::GateWay* _gatewayInterface);
virtual ~GateWayClient(); virtual ~GateWayClient();
void start(const std::string& _ip, uint16_t _port); void start(const std::string& _ip, uint16_t _port, size_t _uid);
void stop(); void stop();
void onClientData(const std::string& _value); void onClientData(const std::string& _value);
void returnMessage(ejson::Object _data);
}; };
} }

View File

@ -0,0 +1,60 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <jus/debug.h>
#include <jus/GateWayService.h>
#include <ejson/ejson.h>
jus::GateWayService::GateWayService(jus::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface) {
}
jus::GateWayService::~GateWayService() {
}
void jus::GateWayService::start(const std::string& _ip, uint16_t _port) {
m_interfaceClient.propertyIp.set(_ip);
m_interfaceClient.propertyPort.set(_port);
m_interfaceClient.propertyServer.set(true);
m_interfaceClient.connect(true);
m_interfaceClient.setInterfaceName("srv-?");
m_dataCallback = m_interfaceClient.signalData.connect(this, &jus::GateWayService::onClientData);
}
void jus::GateWayService::stop() {
m_interfaceClient.disconnect();
}
void jus::GateWayService::SendData(size_t _userSessionId, ejson::Object _data) {
_data.add("client-id", ejson::String(etk::to_string(_userSessionId)));
_data.add("action", ejson::String("call"));
std::string value = _data.generate();
JUS_DEBUG("Send Service: " << value);
m_interfaceClient.write(value);
}
void jus::GateWayService::onClientData(const std::string& _value) {
JUS_DEBUG("On service data: " << _value);
ejson::Object data(_value);
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());
return;
}
m_name = data["connect-service"].toString().get();
m_interfaceClient.setInterfaceName("srv-" + m_name);
JUS_WARNING("Service name configured");
return;
}
if (data.valueExist("client-id") == false) {
JUS_WARNING("Service interface ==> wrong service answer ==> missing 'client-id'");
return;
}
JUS_TODO("plop...........");
}

View File

@ -7,15 +7,30 @@
#include <jus/TcpString.h> #include <jus/TcpString.h>
#include <ememory/memory.h> #include <ememory/memory.h>
#include <esignal/Signal.h>
#include <ejson/ejson.h>
namespace jus { namespace jus {
class GateWay;
class GateWayService { class GateWayService {
public: private:
ememory::SharedPtr<jus::TcpString> m_interfaceService; jus::GateWay* m_gatewayInterface;
std::string m_name; std::string m_name;
public: public:
GateWayService(const ememory::SharedPtr<jus::TcpString>& _interface); jus::TcpString m_interfaceClient;
esignal::Signal<bool> signalIsConnected;
esignal::Connection m_dataCallback;
public:
GateWayService(jus::GateWay* _gatewayInterface);
virtual ~GateWayService(); virtual ~GateWayService();
void start(const std::string& _ip, uint16_t _port);
void stop();
void onClientData(const std::string& _value);
public:
void SendData(size_t _userSessionId, ejson::Object _data);
const std::string& getName() {
return m_name;
}
}; };
} }

28
jus/ParamType.cpp Normal file
View File

@ -0,0 +1,28 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <jus/ParamType.h>
#include <jus/debug.h>
#define generate_basic_type(_type, _name) \
template<> ParamType createType<_type>() {\
return ParamType(_name); \
}
generate_basic_type(void, "void");
generate_basic_type(bool, "bool");
generate_basic_type(float, "float");
generate_basic_type(double, "double");
generate_basic_type(int64_t, "int64");
generate_basic_type(int32_t, "int32");
generate_basic_type(int16_t, "int16");
generate_basic_type(int8_t, "int8");
generate_basic_type(uint64_t, "uint64");
generate_basic_type(uint32_t, "uint32");
generate_basic_type(uint16_t, "uint16");
generate_basic_type(uint8_t, "uint8");
generate_basic_type(std::string, "string");

28
jus/ParamType.h Normal file
View File

@ -0,0 +1,28 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
class ParamType {
protected:
const char* m_typeName;
public:
ParamType(const char* _name = ""):
m_typeName(_name) {
}
const char* getName() const {
return m_typeName;
}
bool operator == (const ParamType& _obj) const {
return m_typeName == _obj.m_typeName;
}
};
template<class JUS_TYPE>
ParamType createType();

View File

@ -6,166 +6,16 @@
#include <jus/Service.h> #include <jus/Service.h>
#include <jus/debug.h> #include <jus/debug.h>
#include <etk/stdTools.h>
#include <ejson/ejson.h>
#include <unistd.h> #include <unistd.h>
generate_basic_type(void, "void");
generate_basic_type(bool, "bool");
generate_basic_type(float, "float");
generate_basic_type(double, "double");
generate_basic_type(int64_t, "int64");
generate_basic_type(int32_t, "int32");
generate_basic_type(int16_t, "int16");
generate_basic_type(int8_t, "int8");
generate_basic_type(uint64_t, "uint64");
generate_basic_type(uint32_t, "uint32");
generate_basic_type(uint16_t, "uint16");
generate_basic_type(uint8_t, "uint8");
generate_basic_type(std::string, "string");
template<> bool convertJsonTo<bool>(const ejson::Value& _value) {
return _value.toBoolean().get();
}
template<> float convertJsonTo<float>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> double convertJsonTo<double>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> int64_t convertJsonTo<int64_t>(const ejson::Value& _value) {
return int64_t(_value.toNumber().get());
}
template<> int32_t convertJsonTo<int32_t>(const ejson::Value& _value) {
//_value.display();
return int32_t(_value.toNumber().get());
}
template<> int16_t convertJsonTo<int16_t>(const ejson::Value& _value) {
return int16_t(_value.toNumber().get());
}
template<> int8_t convertJsonTo<int8_t>(const ejson::Value& _value) {
return int8_t(_value.toNumber().get());
}
template<> uint64_t convertJsonTo<uint64_t>(const ejson::Value& _value) {
return uint64_t(_value.toNumber().get());
}
template<> uint32_t convertJsonTo<uint32_t>(const ejson::Value& _value) {
return uint32_t(_value.toNumber().get());
}
template<> uint16_t convertJsonTo<uint16_t>(const ejson::Value& _value) {
return uint16_t(_value.toNumber().get());
}
template<> uint8_t convertJsonTo<uint8_t>(const ejson::Value& _value) {
return uint8_t(_value.toNumber().get());
}
template<> std::string convertJsonTo<std::string>(const ejson::Value& _value) {
//_value.display();
return _value.toString().get();
}
template<> ejson::Value convertToJson<bool>(const bool& _value) {
return ejson::Boolean(_value);
}
template<> ejson::Value convertToJson<float>(const float& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<double>(const double& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int64_t>(const int64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int32_t>(const int32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int16_t>(const int16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int8_t>(const int8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint64_t>(const uint64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint32_t>(const uint32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint16_t>(const uint16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint8_t>(const uint8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<std::string>(const std::string& _value) {
return ejson::String(_value);
}
template<> bool convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value);
}
template<> float convertStringTo<float>(const std::string& _value) {
return etk::string_to_float(_value);
}
template<> double convertStringTo<double>(const std::string& _value) {
return etk::string_to_double(_value);
}
template<> int64_t convertStringTo<int64_t>(const std::string& _value) {
return etk::string_to_int64_t(_value);
}
template<> int32_t convertStringTo<int32_t>(const std::string& _value) {
return etk::string_to_int32_t(_value);
}
template<> int16_t convertStringTo<int16_t>(const std::string& _value) {
return etk::string_to_int16_t(_value);
}
template<> int8_t convertStringTo<int8_t>(const std::string& _value) {
return etk::string_to_int8_t(_value);
}
template<> uint64_t convertStringTo<uint64_t>(const std::string& _value) {
return etk::string_to_uint64_t(_value);
}
template<> uint32_t convertStringTo<uint32_t>(const std::string& _value) {
return etk::string_to_uint32_t(_value);
}
template<> uint16_t convertStringTo<uint16_t>(const std::string& _value) {
return etk::string_to_uint16_t(_value);
}
template<> uint8_t convertStringTo<uint8_t>(const std::string& _value) {
return etk::string_to_uint8_t(_value);
}
template<> std::string convertStringTo<std::string>(const std::string& _value) {
return _value;
}
bool CmdBase::checkCompatibility(const ParamType& _type, const ejson::Value& _params) {
if (createType<bool>() == _type) {
return _params.isBoolean();
}
if ( createType<int64_t>() == _type
|| createType<int32_t>() == _type
|| createType<int16_t>() == _type
|| createType<int8_t>() == _type
|| createType<uint64_t>() == _type
|| createType<uint32_t>() == _type
|| createType<uint16_t>() == _type
|| createType<uint8_t>() == _type
|| createType<float>() == _type
|| createType<double>() == _type) {
return _params.isNumber();
}
if (createType<std::string>() == _type) {
return _params.isString();
}
return false;
}
bool CmdBase::checkCompatibility(const ParamType& _type, const std::string& _params) {
return false;
}
jus::Service::Service() : jus::Service::Service() :
propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Service::onPropertyChangeIp), propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Service::onPropertyChangeIp),
propertyPort(this, "port", 1984, "Port to connect server", &jus::Service::onPropertyChangePort), propertyPort(this, "port", 1982, "Port to connect server", &jus::Service::onPropertyChangePort),
m_id(0) { m_id(0) {
m_interfaceClient.propertyIp.set(*propertyIp); m_interfaceClient.propertyIp.set(*propertyIp);
m_interfaceClient.propertyPort.set(*propertyPort); m_interfaceClient.propertyPort.set(*propertyPort);
@ -192,9 +42,10 @@ void jus::Service::onPropertyChangePort(){
} }
void jus::Service::connect(){ void jus::Service::connect(const std::string& _serviceName){
JUS_DEBUG("connect [START]"); JUS_DEBUG("connect [START]");
m_interfaceClient.connect(); m_interfaceClient.connect();
m_interfaceClient.write(std::string("{\"connect-service\":\"") + _serviceName + "\"}");
JUS_DEBUG("connect [STOP]"); JUS_DEBUG("connect [STOP]");
} }
@ -205,13 +56,26 @@ void jus::Service::disconnect(){
} }
ejson::Object jus::Service::callJson(const ejson::Object& _obj) { ejson::Object jus::Service::callJson(const ejson::Object& _obj) {
/* std::string action = _obj["action"].toString().get();
JUS_VERBOSE("Call JSON [START] "); if (action == "new") {
std::string tmpVal = _obj.generate(); uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
JUS_DEBUG("Call JSON '" << tmpVal << "'"); std::string userName = _obj["user"].toString().get();
m_interfaceClient.write(_obj.generate()); clientConnect(clientId, userName);
std::string ret = asyncRead(); ejson::Object tmpp;
JUS_VERBOSE("Call JSON [STOP]"); tmpp.add("return", ejson::String("OK"));
*/ return tmpp;
} else if (action == "delete") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
clientDisconnect(clientId);
ejson::Object tmpp;
tmpp.add("return", ejson::String("OK"));
return tmpp;
} else if ( action == "call"
|| action == "") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
return callJson2(clientId, _obj);
} else {
// TODO : ...
}
return ejson::Object(); return ejson::Object();
} }

View File

@ -8,240 +8,10 @@
#include <jus/TcpString.h> #include <jus/TcpString.h>
#include <eproperty/Value.h> #include <eproperty/Value.h>
#include <ejson/ejson.h> #include <ejson/ejson.h>
#include <jus/AbstractFunctionTypeDirect.h>
#include <jus/AbstractFunctionTypeClass.h>
#include <jus/debug.h> #include <jus/debug.h>
class ParamType {
protected:
const char* m_typeName;
public:
ParamType(const char* _name = ""):
m_typeName(_name) {
}
const char* getName() const {
return m_typeName;
}
bool operator == (const ParamType& _obj) const {
return m_typeName == _obj.m_typeName;
}
};
template<class JUS_TYPE>
ParamType createType();
#define generate_basic_type(_type, _name) \
template<> ParamType createType<_type>() {\
return ParamType(_name); \
}
class CmdBase {
protected:
const std::string m_name;
public:
const std::string& getName() const {
return m_name;
}
protected:
const std::string m_description;
public:
const std::string& getDescription() const {
return m_description;
}
protected:
CmdBase(const std::string& _name,
const std::string& _desc):
m_name(_name),
m_description(_desc) {
}
public:
virtual ~CmdBase() {};
bool checkCompatibility(const ParamType& _type, const ejson::Value& _params);
bool checkCompatibility(const ParamType& _type, const std::string& _params);
public:
virtual std::string getPrototype() const = 0;
virtual ejson::Value executeJson(const ejson::Array& _params) = 0;
virtual std::string executeString(const std::vector<std::string>& _params) = 0;
};
template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value);
template<class JUS_TYPE>
JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
template <class, class...>
class TypeList;
template <class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeCallJson(JUS_RETURN (*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = m_paramCount-1;
return convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class... JUS_TYPES>
ejson::Value executeCallJson(void (*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = m_paramCount-1;
_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
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((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = m_paramCount-1;
return etk::to_string(_func(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((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = m_paramCount-1;
_func(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class... JUS_TYPES>
class TypeList: public CmdBase {
protected:
static const ParamType m_returnType;
static const ParamType m_paramType[sizeof...(JUS_TYPES)];
static const int32_t m_paramCount;
public:
using functionType = JUS_RETURN (*)(JUS_TYPES...);
functionType m_function;
TypeList(const std::string& _name, const std::string& _desc, functionType _fptr):
CmdBase(_name, _desc),
m_function(_fptr) {
}
std::string getPrototype() const override {
std::string ret;
ret += m_returnType.getName();
ret += " ";
ret += m_name;
ret += "(";
for (size_t iii=0; iii<m_paramCount; ++iii) {
if (iii != 0) {
ret += ", ";
}
ret += m_paramType[iii].getName();
}
ret += ");";
return ret;
}
ejson::Value executeJson(const ejson::Array& _params) override {
ejson::Object out;
// check parameter number
if (_params.size() != m_paramCount) {
JUS_ERROR("Wrong number of Parameters ...");
out.add("error", ejson::String("WRONG-PARAMETER-NUMBER"));
std::string help = "request ";
help += etk::to_string(_params.size());
help += " parameters and need ";
help += etk::to_string(m_paramCount);
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<m_paramCount; ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
return out;
}
}
// execute cmd:
ejson::Value retVal = executeCallJson(m_function, _params);
out.add("return", retVal);
return out;
}
std::string executeString(const std::vector<std::string>& _params) override {
std::string out;
// check parameter number
if (_params.size() != m_paramCount) {
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(m_paramCount);
out += " parameters. prototype function:";
out += getPrototype();
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<m_paramCount; ++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 = executeCallString(m_function, _params);
return out;
}
};
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType TypeList<JUS_RETURN, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType TypeList<JUS_RETURN, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <class JUS_RETURN, class... JUS_TYPES>
const int32_t TypeList<JUS_RETURN, JUS_TYPES...>::m_paramCount = sizeof...(JUS_TYPES);
template <typename JUS_RETURN, typename... JUS_TYPES>
CmdBase* createCmd(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) {
return new TypeList<JUS_RETURN, JUS_TYPES...>(_name, _desc, _fffp);
}
static double mulllll(double _val1) { static double mulllll(double _val1) {
double _val2 = 2.0f; double _val2 = 2.0f;
JUS_ERROR("Call with parameter : " << _val1); JUS_ERROR("Call with parameter : " << _val1);
@ -278,7 +48,8 @@ namespace jus {
virtual ~Service(); virtual ~Service();
// Genenric function call: // Genenric function call:
ejson::Object callJson(const ejson::Object& _obj); ejson::Object callJson(const ejson::Object& _obj);
void connect(); virtual ejson::Object callJson2(size_t _clientId, const ejson::Object& _obj) = 0;
void connect(const std::string& _serviceName);
void disconnect(); void disconnect();
private: private:
void onClientData(const std::string& _value); void onClientData(const std::string& _value);
@ -286,47 +57,14 @@ namespace jus {
private: private:
void onPropertyChangeIp(); void onPropertyChangeIp();
void onPropertyChangePort(); void onPropertyChangePort();
protected: public:
void createSignatureInternal(std::vector<std::string>& _signature) {
// Finish recursive parse ...
}
template<class... _ARGS>
void createSignatureInternal(std::vector<std::string>& _signature, const std::string& _param, _ARGS&&... _args) {
_signature.push_back("string");
createSignatureInternal(_signature, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createSignatureInternal(std::vector<std::string>& _signature, const bool& _param, _ARGS&&... _args) {
_signature.push_back("bool");
createSignatureInternal(_signature, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createSignatureInternal(std::vector<std::string>& _signature, const double& _param, _ARGS&&... _args) {
_signature.push_back("double");
createSignatureInternal(_signature, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
void createSignatureInternal(std::vector<std::string>& _signature, const int32_t& _param, _ARGS&&... _args) {
_signature.push_back("int32");
createSignatureInternal(_signature, std::forward<_ARGS>(_args)...);
}
template<class... _ARGS>
std::vector<std::string> createSignature(_ARGS&&... _args) {
std::vector<std::string> signature;
createSignatureInternal(signature, std::forward<_ARGS>(_args)...);
return signature;
}
template<class JUS_RETURN_VALUE, template<class JUS_RETURN_VALUE,
class JUS_CLASS_TYPE,
class... JUS_FUNC_ARGS_TYPE> class... JUS_FUNC_ARGS_TYPE>
void advertise(const std::string& _name, void advertise(const std::string& _name,
JUS_RETURN_VALUE (JUS_CLASS_TYPE::*_func)(const JUS_FUNC_ARGS_TYPE&... _args), JUS_RETURN_VALUE (*_func)(JUS_FUNC_ARGS_TYPE... _args),
const std::string& _desc) { const std::string& _desc) {
//AbstractFunction* tmp = createAbstractFunctionDirect(_name, &mulllll);
//CmdBase* tmp = createCmd(_name, &mulllll); AbstractFunction* tmp = createAbstractFunctionDirect(_name, "desc", &mulllll);
CmdBase* tmp = createCmd(_name, "desc", &mulllll);
JUS_ERROR("Signature : " << tmp->getPrototype()); JUS_ERROR("Signature : " << tmp->getPrototype());
{ {
ejson::Array param; ejson::Array param;
@ -337,7 +75,7 @@ namespace jus {
} }
tmp = createCmd(_name, "desc", &mulllll2); tmp = createAbstractFunctionDirect(_name, "desc", &mulllll2);
JUS_ERROR("Signature2 : " << tmp->getPrototype()); JUS_ERROR("Signature2 : " << tmp->getPrototype());
{ {
ejson::Array param; ejson::Array param;
@ -347,20 +85,80 @@ namespace jus {
JUS_ERROR(" return: "); JUS_ERROR(" return: ");
out.display(); out.display();
} }
tmp = createCmd(_name, "desc", &mulllll3); tmp = createAbstractFunctionDirect(_name, "desc", &mulllll3);
JUS_ERROR("Signature3 : " << tmp->getPrototype()); JUS_ERROR("Signature3 : " << tmp->getPrototype());
JUS_ERROR(" return: " << tmp->executeString(etk::split("3.5 false", ' '))); JUS_ERROR(" return: " << tmp->executeString(etk::split("3.5 false", ' ')));
tmp = createCmd(_name, "desc", &mulllll4); tmp = createAbstractFunctionDirect(_name, "desc", &mulllll4);
JUS_ERROR("Signature4 : " << tmp->getPrototype()); JUS_ERROR("Signature4 : " << tmp->getPrototype());
/* }
std::vector<std::string> plop = createSignature(_args): /**
JUS_ERROR("signature:"); * @brief A extern client connect on specific user
for (auto& it : plop) { * @param[in] _clientSessionID Source session Id on the client
JUS_ERROR(" - " << it); * @param[in] _userName User name of the client to connect
* @todo Set a relur like ==> service not availlable / service close / service maintenance / service right reject
*/
virtual void clientConnect(size_t _clientSessionID, const std::string& _userName) = 0;
virtual void clientDisconnect(size_t _clientSessionID) = 0;
};
template<class JUS_TYPE_SERVICE, class JUS_USER_ACCESS>
class ServiceType : public jus::Service {
private:
JUS_USER_ACCESS& m_getUserInterface;
// no need of shared_ptr or unique_ptr (if service die all is lost and is client die, the gateway notify us...)
std::map<size_t, JUS_TYPE_SERVICE*> m_interface;
std::vector<AbstractFunction*> m_listFunction;
public:
template<class JUS_RETURN_VALUE,
class JUS_CLASS_TYPE,
class... JUS_FUNC_ARGS_TYPE>
void advertise(const std::string& _name,
JUS_RETURN_VALUE (JUS_CLASS_TYPE::*_func)(JUS_FUNC_ARGS_TYPE... _args),
const std::string& _desc) {
// TODO: check if fucntion does not exist ...
AbstractFunction* tmp = createAbstractFunctionClass(_name, _desc, _func);
m_listFunction.push_back(tmp);
}
ServiceType(JUS_USER_ACCESS& _interface):
m_getUserInterface(_interface) {
}
void clientConnect(size_t _clientSessionID, const std::string& _userName) {
// TODO : Set a mutex ...
m_interface.insert(std::make_pair(_clientSessionID, new JUS_TYPE_SERVICE(m_getUserInterface.getUser(_userName))));
}
void clientDisconnect(size_t _clientSessionID) {
auto it = m_interface.find(_clientSessionID);
if (it != m_interface.end()) {
// noting to do ==> user never conected.
return;
} }
*/ // TODO : Set a mutex ...
m_interface.erase(it);
}
ejson::Object callJson2(size_t _clientSessionID, const ejson::Object& _obj) {
ejson::Object out;
auto it = m_interface.find(_clientSessionID);
if (it == m_interface.end()) {
out.add("error", ejson::String("CLIENT-UNKNOW"));
return out;
}
std::string call = _obj["call"].toString().get();
const ejson::Array param = _obj["param"].toArray();
for (auto &it2 : m_listFunction) {
if (it2 == nullptr) {
continue;
}
if (it2->getName() != call) {
continue;
}
JUS_TYPE_SERVICE* elem = it->second;
return it2->executeJson(param, (void*)elem).toObject();
}
out.add("error", ejson::String("FUNCTION-UNKNOW"));
return out;
} }
}; };
} }

View File

@ -25,6 +25,10 @@ jus::TcpString::~TcpString() {
disconnect(); disconnect();
} }
void jus::TcpString::setInterfaceName(const std::string& _name) {
ethread::setName(*m_thread, "Tcp-" + _name);
}
void jus::TcpString::threadCallback() { void jus::TcpString::threadCallback() {
ethread::setName("TcpString-input"); ethread::setName("TcpString-input");
// Connect ... // Connect ...
@ -52,7 +56,7 @@ void jus::TcpString::threadCallback() {
JUS_DEBUG("End of thread"); JUS_DEBUG("End of thread");
} }
void jus::TcpString::connect(){ void jus::TcpString::connect(bool _async){
JUS_DEBUG("connect [START]"); JUS_DEBUG("connect [START]");
m_threadRunning = true; m_threadRunning = true;
m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr); m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr);
@ -61,12 +65,17 @@ void jus::TcpString::connect(){
JUS_ERROR("creating callback thread!"); JUS_ERROR("creating callback thread!");
return; return;
} }
while ( m_threadRunning == true while ( _async == false
&& m_threadRunning == true
&& m_connection.getConnectionStatus() != enet::Tcp::status::link) { && m_connection.getConnectionStatus() != enet::Tcp::status::link) {
usleep(50000); usleep(50000);
} }
//ethread::setPriority(*m_receiveThread, -6); //ethread::setPriority(*m_receiveThread, -6);
JUS_DEBUG("connect [STOP]"); if (_async == true) {
JUS_DEBUG("connect [STOP] async mode");
} else {
JUS_DEBUG("connect [STOP]");
}
} }
void jus::TcpString::disconnect(){ void jus::TcpString::disconnect(){

View File

@ -25,8 +25,9 @@ namespace jus {
public: public:
TcpString(); TcpString();
virtual ~TcpString(); virtual ~TcpString();
void connect(); void connect(bool _async = false);
void disconnect(); void disconnect();
void setInterfaceName(const std::string& _name);
int32_t write(const std::string& _data); int32_t write(const std::string& _data);
std::string asyncRead(); std::string asyncRead();
private: private:

View File

@ -32,6 +32,10 @@ def create(target, module_name):
]) ])
my_module.add_path(tools.get_current_path(__file__)) my_module.add_path(tools.get_current_path(__file__))
my_module.add_src_file([ my_module.add_src_file([
'jus/AbstractFunction.cpp',
'jus/AbstractFunctionTypeDirect.cpp',
'jus/AbstractFunctionTypeClass.cpp',
'jus/ParamType.cpp',
'jus/Client.cpp', 'jus/Client.cpp',
'jus/GateWay.cpp', 'jus/GateWay.cpp',
'jus/GateWayService.cpp', 'jus/GateWayService.cpp',
@ -40,6 +44,10 @@ def create(target, module_name):
'jus/TcpString.cpp', 'jus/TcpString.cpp',
]) ])
my_module.add_header_file([ my_module.add_header_file([
'jus/AbstractFunction.h',
'jus/AbstractFunctionTypeDirect.h',
'jus/AbstractFunctionTypeClass.h',
'jus/ParamType.h',
'jus/debug.h', 'jus/debug.h',
'jus/Client.h', 'jus/Client.h',
'jus/GateWay.h', 'jus/GateWay.h',

View File

@ -42,13 +42,22 @@ int main(int _argc, const char *_argv[]) {
tmp.push_back(22); tmp.push_back(22);
tmp.push_back(333); tmp.push_back(333);
tmp.push_back(4444); tmp.push_back(4444);
int32_t val = client1.call_i("getServiceCount", tmp, "soucou", false); int32_t val = client1.call_i("", "getServiceCount", tmp, "coucou", false);
APPL_INFO("Nb services = " << val); APPL_INFO("Nb services = " << val);
std::vector<std::string> val2 = client1.call_vs("getServiceList"); std::vector<std::string> val2 = client1.call_vs("", "getServiceList");
APPL_INFO("List services:"); APPL_INFO("List services:");
for (auto &it: val2) { for (auto &it: val2) {
APPL_INFO(" - " << it); APPL_INFO(" - " << it);
} }
// TODO: add return value
bool valConnect = client1.call_b("", "link", "serviceTest1");
APPL_INFO("Link service 'serviceTest1' ret=" << valConnect);
bool retCall = client1.call_d("serviceTest1", "mul", 13.1, 2.0);
APPL_INFO("serviceTest1.mul = " << retCall);
valConnect = client1.call_b("", "unlink", "serviceTest1");
APPL_INFO("un-Link service 'serviceTest1' ret=" << valConnect);
int32_t iii=0; int32_t iii=0;
while (iii < 3) { while (iii < 3) {

View File

@ -11,15 +11,49 @@
#include <etk/stdTools.h> #include <etk/stdTools.h>
namespace appl { namespace appl {
class Service1 : public jus::Service { class User {
public:
User() {
APPL_WARNING("new USER");
}
~User() {
APPL_WARNING("delete USER");
}
};
class UserManager {
private: private:
double mul(const double& _val1) {//, const double& _val2) { std::map<std::string, ememory::SharedPtr<appl::User>> m_listLoaded;
public:
UserManager() {
}
ememory::SharedPtr<appl::User> getUser(const std::string& _userName) {
// TODO : Lock ...
auto it = m_listLoaded.find(_userName);
if (it != m_listLoaded.end()) {
// User already loaded:
return it->second;
}
// load New User:
ememory::SharedPtr<appl::User> tmp(new appl::User);
m_listLoaded.insert(std::make_pair(_userName, tmp));
return tmp;
}
};
class Calculator {
private:
ememory::SharedPtr<appl::User> m_user;
public:
double mul(double _val1) {//, const double& _val2) {
double _val2 = 1.0f; double _val2 = 1.0f;
return _val1*_val2; return _val1*_val2;
} }
public: public:
Service1() { Calculator(ememory::SharedPtr<appl::User> _user) :
advertise("mul", &appl::Service1::mul, "simple multiplication to test double IO"); m_user(_user) {
//advertise("mul", &appl::Service1::mul, "simple multiplication to test double IO");
} }
}; };
} }
@ -27,13 +61,15 @@ namespace appl {
int main(int _argc, const char *_argv[]) { int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv); etk::init(_argc, _argv);
appl::Service1 service1; appl::UserManager userMng;
jus::ServiceType<appl::Calculator, appl::UserManager> serviceInterface(userMng);
serviceInterface.advertise("mul", &appl::Calculator::mul, "simple multiplication to test double IO");
for (int32_t iii=0; iii<_argc ; ++iii) { for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii]; std::string data = _argv[iii];
if (etk::start_with(data, "--ip=") == true) { if (etk::start_with(data, "--ip=") == true) {
service1.propertyIp.set(std::string(&data[5])); serviceInterface.propertyIp.set(std::string(&data[5]));
} else if (etk::start_with(data, "--port=") == true) { } else if (etk::start_with(data, "--port=") == true) {
service1.propertyPort.set(etk::string_to_uint16_t(std::string(&data[7]))); serviceInterface.propertyPort.set(etk::string_to_uint16_t(std::string(&data[7])));
} else if ( data == "-h" } else if ( data == "-h"
|| data == "--help") { || data == "--help") {
APPL_PRINT(etk::getApplicationName() << " - help : "); APPL_PRINT(etk::getApplicationName() << " - help : ");
@ -46,16 +82,14 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO("=================================="); APPL_INFO("==================================");
APPL_INFO("== JUS test service1 start =="); APPL_INFO("== JUS test service1 start ==");
APPL_INFO("=================================="); APPL_INFO("==================================");
/* serviceInterface.connect("serviceTest1");
service1.connect();
int32_t iii=0; int32_t iii=0;
while (true) { while (true) {
usleep(500000); usleep(500000);
APPL_INFO("Appl in waiting ... " << iii << "/inf"); APPL_INFO("service in waiting ... " << iii << "/inf");
iii++; iii++;
} }
service1.disconnect(); serviceInterface.disconnect();
*/
APPL_INFO("=================================="); APPL_INFO("==================================");
APPL_INFO("== JUS test service1 stop =="); APPL_INFO("== JUS test service1 stop ==");
APPL_INFO("=================================="); APPL_INFO("==================================");