[DEV] start test binary comminicaution
This commit is contained in:
parent
0d73df3593
commit
3a141c64b2
@ -261,10 +261,10 @@ ejson::Object jus::createCallJson(uint64_t _transactionId, const std::string& _f
|
||||
return callElem;
|
||||
}
|
||||
|
||||
ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service) {
|
||||
ejson::Object jus::createBaseCall(uint64_t _transactionId, const std::string& _functionName, const uint32_t& _serviceId) {
|
||||
ejson::Object obj;
|
||||
if (_service.size() != 0) {
|
||||
obj.add("service", ejson::String(_service));
|
||||
if (_serviceId != 0) {
|
||||
obj.add("service", ejson::Number(_serviceId));
|
||||
}
|
||||
obj.add("call", ejson::String(_functionName));
|
||||
obj.add("id", ejson::Number(_transactionId));
|
||||
|
@ -77,7 +77,7 @@ namespace jus {
|
||||
// ============================================================
|
||||
// == JSON
|
||||
// ============================================================
|
||||
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const std::string& _service="");
|
||||
ejson::Object createBaseCall(uint64_t _transactionId, const std::string& _functionName, const uint32_t& _serviceId=0);
|
||||
|
||||
void createParam(std::vector<ActionAsyncClient>& _asyncAction,
|
||||
int32_t _paramId,
|
||||
@ -113,8 +113,8 @@ namespace jus {
|
||||
return callElem;
|
||||
}
|
||||
template<class... _ARGS>
|
||||
ejson::Object createCallService(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const std::string& _serviceName, const std::string& _functionName, _ARGS&&... _args) {
|
||||
ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceName);
|
||||
ejson::Object createCallService(std::vector<ActionAsyncClient>& _asyncAction, uint64_t _transactionId, const uint32_t& _serviceId, const std::string& _functionName, _ARGS&&... _args) {
|
||||
ejson::Object callElem = createBaseCall(_transactionId, _functionName, _serviceId);
|
||||
createParam(_asyncAction, 0, callElem, std::forward<_ARGS>(_args)...);
|
||||
return callElem;
|
||||
}
|
||||
|
@ -7,17 +7,70 @@
|
||||
#include <jus/Buffer.h>
|
||||
#include <jus/debug.h>
|
||||
|
||||
namespace etk {
|
||||
template<> std::string to_string<enum jus::Buffer::typeMessage>(const enum jus::Buffer::typeMessage& _value) {
|
||||
switch (_value) {
|
||||
case jus::Buffer::typeMessage::call:
|
||||
return "call";
|
||||
case jus::Buffer::typeMessage::answer:
|
||||
return "answer";
|
||||
case jus::Buffer::typeMessage::event:
|
||||
return "event";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
std::ostream& jus::operator <<(std::ostream& _os, const std::vector<enum jus::Buffer::typeMessage>& _value) {
|
||||
_os << etk::to_string(_value);
|
||||
return _os;
|
||||
}
|
||||
|
||||
static enum jus::Buffer::typeMessage getTypeType(uint16_t _value) {
|
||||
switch (_value) {
|
||||
case 1:
|
||||
return jus::Buffer::typeMessage::call;
|
||||
case 2:
|
||||
return jus::Buffer::typeMessage::answer;
|
||||
case 4:
|
||||
return jus::Buffer::typeMessage::event;
|
||||
}
|
||||
return jus::Buffer::typeMessage::call;
|
||||
}
|
||||
|
||||
jus::Buffer::Buffer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
void jus::Buffer::composeWith(const std::vector<uint8_t>& _buffer) {
|
||||
clear();
|
||||
m_header.lenght = _buffer.size();
|
||||
memcpy(&m_header + 4, &_buffer[0], sizeof(headerBin)-4);
|
||||
JUS_INFO("Get binary message : ");
|
||||
JUS_INFO(" lenght = " << m_header.lenght);
|
||||
JUS_INFO(" versionProtocol = " << m_header.versionProtocol);
|
||||
JUS_INFO(" transactionID = " << m_header.transactionID);
|
||||
JUS_INFO(" clientID = " << m_header.clientID);
|
||||
JUS_INFO(" partID = " << m_header.partID);
|
||||
enum jus::Buffer::typeMessage ttype = getTypeType(m_header.typeMessage);
|
||||
JUS_INFO(" typeMessage = " << ttype);
|
||||
JUS_TODO(" ...");
|
||||
}
|
||||
|
||||
void jus::Buffer::clear() {
|
||||
m_data.clear();
|
||||
m_paramOffset.clear();
|
||||
m_header.clear();
|
||||
}
|
||||
std::string jus::Buffer::generateHumanString() {
|
||||
return "jus::Buffer ...";
|
||||
std::string out = "jus::Buffer Lenght=: ";
|
||||
out += etk::to_string(m_header.lenght);
|
||||
out += " v=" + etk::to_string(m_header.versionProtocol);
|
||||
out += " id=" + etk::to_string(m_header.transactionID);
|
||||
out += " cId=" + etk::to_string(m_header.clientID);
|
||||
out += " pId=" + etk::to_string(m_header.partID);
|
||||
enum jus::Buffer::typeMessage type = getTypeType(m_header.typeMessage);
|
||||
out += " type=" + etk::to_string(type);
|
||||
return out;
|
||||
}
|
||||
|
||||
uint16_t jus::Buffer::getProtocalVersion() {
|
||||
@ -78,6 +131,15 @@ uint16_t jus::Buffer::getNumberParameter() {
|
||||
}
|
||||
|
||||
|
||||
void jus::Buffer::addParameter() {
|
||||
int32_t currentOffset = m_data.size();
|
||||
m_paramOffset.push_back(currentOffset);
|
||||
m_data.push_back('v');
|
||||
m_data.push_back('o');
|
||||
m_data.push_back('i');
|
||||
m_data.push_back('d');
|
||||
m_data.push_back('\0');
|
||||
}
|
||||
template<>
|
||||
void jus::Buffer::addParameter<std::string>(const std::string& _value) {
|
||||
int32_t currentOffset = m_data.size();
|
||||
@ -223,6 +285,21 @@ void jus::Buffer::addParameter<double>(const double& _value) {
|
||||
m_data.resize(m_data.size()+8);
|
||||
memcpy(&m_data[currentOffset], &_value, 8);
|
||||
}
|
||||
template<>
|
||||
void jus::Buffer::addParameter<bool>(const bool& _value) {
|
||||
int32_t currentOffset = m_data.size();
|
||||
m_paramOffset.push_back(currentOffset);
|
||||
m_data.push_back('b');
|
||||
m_data.push_back('o');
|
||||
m_data.push_back('o');
|
||||
m_data.push_back('l');
|
||||
m_data.push_back('\0');
|
||||
if (_value == true) {
|
||||
m_data.push_back('T');
|
||||
} else {
|
||||
m_data.push_back('F');
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string jus::Buffer::internalGetParameter<std::string>(int32_t _id) {
|
||||
@ -302,7 +379,11 @@ int8_t jus::Buffer::internalGetParameter<int8_t>(int32_t _id) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void jus::Buffer::addError(const std::string& _value, const std::string& _comment) {
|
||||
addParameter();
|
||||
addParameter(_value);
|
||||
addParameter(_comment);
|
||||
}
|
||||
|
||||
std::string jus::Buffer::getCall() {
|
||||
std::string out;
|
||||
|
36
jus/Buffer.h
36
jus/Buffer.h
@ -29,6 +29,7 @@ namespace jus {
|
||||
======================
|
||||
== call
|
||||
======================
|
||||
U16 param count
|
||||
U16[param count] parameters offset (first offset is the "callName" and limit size of the number of parameter
|
||||
CALL Name (funtion name)
|
||||
[param 1]
|
||||
@ -38,8 +39,11 @@ namespace jus {
|
||||
======================
|
||||
== Answer
|
||||
======================
|
||||
U16 ErrorOffset
|
||||
[return value 1]
|
||||
U16 param count = 3
|
||||
U16[param count]
|
||||
[param 1] (return value)
|
||||
[param 2] (error value)
|
||||
[param 3] (error help)
|
||||
[error] (constituated with 2 strings (error type and comment)
|
||||
======================
|
||||
== event
|
||||
@ -86,8 +90,28 @@ namespace jus {
|
||||
headerBin m_header;
|
||||
std::vector<uint16_t> m_paramOffset;
|
||||
std::vector<uint8_t> m_data;
|
||||
public:
|
||||
const uint8_t* getHeader() const {
|
||||
return reinterpret_cast<const uint8_t*>(&m_header);
|
||||
}
|
||||
uint32_t getHeaderSize() const {
|
||||
return sizeof(headerBin);
|
||||
}
|
||||
const uint8_t* getParam() const {
|
||||
return reinterpret_cast<const uint8_t*>(&m_paramOffset[0]);
|
||||
}
|
||||
uint32_t getParamSize() const {
|
||||
return m_paramOffset.size() * 2;
|
||||
}
|
||||
const uint8_t* getData() const {
|
||||
return &m_data[0];
|
||||
}
|
||||
uint32_t getDataSize() const {
|
||||
return m_data.size();
|
||||
}
|
||||
public:
|
||||
Buffer();
|
||||
void composeWith(const std::vector<uint8_t>& _buffer);
|
||||
std::string generateHumanString();
|
||||
void clear();
|
||||
uint16_t getProtocalVersion();
|
||||
@ -114,6 +138,7 @@ namespace jus {
|
||||
};
|
||||
enum typeMessage getType();
|
||||
void setType(enum typeMessage _value);
|
||||
|
||||
// ===============================================
|
||||
// == Section call
|
||||
// ===============================================
|
||||
@ -127,6 +152,7 @@ namespace jus {
|
||||
|
||||
template<class JUS_TYPE_DATA>
|
||||
void addParameter(const JUS_TYPE_DATA& _value);
|
||||
void addParameter();
|
||||
|
||||
template<class JUS_TYPE_DATA>
|
||||
JUS_TYPE_DATA getParameter(int32_t _id) {
|
||||
@ -139,7 +165,11 @@ namespace jus {
|
||||
// ===============================================
|
||||
public:
|
||||
template<class JUS_TYPE_DATA>
|
||||
void addAnswer(const JUS_TYPE_DATA& _value);
|
||||
void addAnswer(const JUS_TYPE_DATA& _value) {
|
||||
addParameter(_value);
|
||||
}
|
||||
void addError(const std::string& _value, const std::string& _comment);
|
||||
};
|
||||
std::ostream& operator <<(std::ostream& _os, const std::vector<enum jus::Buffer::typeMessage>& _value);
|
||||
}
|
||||
|
||||
|
@ -146,6 +146,15 @@ bool jus::Client::connect(const std::string& _remoteUserToConnect){
|
||||
enet::Tcp connection = std::move(enet::connectTcpClient(*propertyIp, *propertyPort));
|
||||
m_interfaceClient.setInterface(std::move(connection));
|
||||
m_interfaceClient.connect();
|
||||
// Force mode binary:
|
||||
jus::Future<bool> retBin = call("setMode", "BIN").wait();
|
||||
if (retBin.get() == true) {
|
||||
m_interfaceMode = jus::connectionMode::modeBinary;
|
||||
JUS_INFO("Connection jump in BINARY ...");
|
||||
} else {
|
||||
// stay in JSON
|
||||
}
|
||||
|
||||
jus::Future<bool> ret = call("connectToUser", _remoteUserToConnect, "jus-client");
|
||||
ret.wait();
|
||||
if (ret.hasError() == true) {
|
||||
|
@ -25,6 +25,7 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, jus::FutureData::ObserverFi
|
||||
m_data->m_transactionId = _transactionId;
|
||||
m_data->m_isFinished = false;
|
||||
m_data->m_isSynchronous = false;
|
||||
m_data->m_mode = false;
|
||||
m_data->m_callbackFinish = _callback;
|
||||
}
|
||||
|
||||
@ -44,6 +45,7 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Ob
|
||||
m_data->m_transactionId = _transactionId;
|
||||
m_data->m_isFinished = _isFinished;
|
||||
m_data->m_isSynchronous = false;
|
||||
m_data->m_mode = false;
|
||||
m_data->m_returnData = _returnData;
|
||||
m_data->m_callbackFinish = _callback;
|
||||
if (m_data->m_isFinished == true) {
|
||||
@ -54,6 +56,25 @@ jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, ejson::Ob
|
||||
}
|
||||
}
|
||||
|
||||
jus::FutureBase::FutureBase(uint64_t _transactionId, bool _isFinished, jus::Buffer _returnData, jus::FutureData::ObserverFinish _callback) {
|
||||
m_data = std::make_shared<jus::FutureData>();
|
||||
if (m_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_data->m_sendTime = std::chrono::steady_clock::now();
|
||||
m_data->m_transactionId = _transactionId;
|
||||
m_data->m_isFinished = _isFinished;
|
||||
m_data->m_isSynchronous = false;
|
||||
m_data->m_mode = true;
|
||||
m_data->m_returnDataBinary = _returnData;
|
||||
m_data->m_callbackFinish = _callback;
|
||||
if (m_data->m_isFinished == true) {
|
||||
m_data->m_receiveTime = std::chrono::steady_clock::now();
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
m_data->m_callbackFinish(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::chrono::nanoseconds jus::FutureBase::getTransmitionTime() {
|
||||
if (m_data == nullptr) {
|
||||
return std::chrono::nanoseconds(0);
|
||||
@ -74,6 +95,7 @@ bool jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
|
||||
JUS_ERROR(" Not a valid future ...");
|
||||
return true;
|
||||
}
|
||||
m_data->m_mode = false;
|
||||
m_data->m_receiveTime = std::chrono::steady_clock::now();
|
||||
if (m_data->m_isSynchronous == true) {
|
||||
m_data->m_returnData = _returnValue;
|
||||
@ -108,6 +130,48 @@ bool jus::FutureBase::setAnswer(const ejson::Object& _returnValue) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool jus::FutureBase::setAnswer(const jus::Buffer& _returnValue) {
|
||||
if (m_data == nullptr) {
|
||||
JUS_ERROR(" Not a valid future ...");
|
||||
return true;
|
||||
}
|
||||
m_data->m_mode = true;
|
||||
m_data->m_receiveTime = std::chrono::steady_clock::now();
|
||||
if (m_data->m_isSynchronous == true) {
|
||||
m_data->m_returnDataBinary = _returnValue;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* TODO : ...
|
||||
if (_returnValue.valueExist("part") == true) {
|
||||
uint64_t idPart = _returnValue["part"].toNumber().getU64();
|
||||
if (idPart == 0) {
|
||||
m_data->m_returnData = _returnValue;
|
||||
} else {
|
||||
m_data->m_returnDataPart.push_back(_returnValue["data"]);
|
||||
}
|
||||
if (_returnValue.valueExist("finish") == true) {
|
||||
if (_returnValue["finish"].toBoolean().get() == true) {
|
||||
m_data->m_isFinished = true;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// finish is false ==> normal case ...
|
||||
}
|
||||
return false;
|
||||
}
|
||||
m_data->m_returnData = _returnValue;
|
||||
m_data->m_isFinished = true;
|
||||
if (m_data->m_callbackFinish != nullptr) {
|
||||
return m_data->m_callbackFinish(*this);
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
void jus::FutureBase::setSynchronous() {
|
||||
if (m_data == nullptr) {
|
||||
return;
|
||||
|
@ -19,6 +19,7 @@ namespace jus {
|
||||
uint64_t m_transactionId;
|
||||
bool m_isSynchronous;
|
||||
bool m_isFinished;
|
||||
bool m_mode;
|
||||
ejson::Object m_returnData;
|
||||
jus::Buffer m_returnDataBinary;
|
||||
std::vector<ejson::Value> m_returnDataPart;
|
||||
|
@ -12,10 +12,14 @@
|
||||
|
||||
#include <jus/AbstractFunction.h>
|
||||
|
||||
|
||||
static const std::string protocolError = "PROTOCOL-ERROR";
|
||||
|
||||
jus::GateWayClient::GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayInterface) :
|
||||
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 --");
|
||||
@ -45,12 +49,16 @@ void jus::GateWayClient::stop() {
|
||||
continue;
|
||||
}
|
||||
ejson::Object linkService;
|
||||
linkService.add("event", ejson::String("delete"));
|
||||
linkService.add("call", ejson::String("_delete"));
|
||||
linkService.add("id", ejson::Number(m_transactionLocalId++));
|
||||
linkService.add("param", ejson::Array());
|
||||
it->SendData(m_uid, linkService);
|
||||
}
|
||||
if (m_userService != nullptr) {
|
||||
ejson::Object linkService;
|
||||
linkService.add("event", ejson::String("delete"));
|
||||
linkService.add("call", ejson::String("_delete"));
|
||||
linkService.add("id", ejson::Number(m_transactionLocalId++));
|
||||
linkService.add("param", ejson::Array());
|
||||
m_userService->SendData(m_uid2, linkService);
|
||||
m_userService = nullptr;
|
||||
}
|
||||
@ -62,23 +70,42 @@ bool jus::GateWayClient::isAlive() {
|
||||
return m_interfaceClient.isActive();
|
||||
}
|
||||
|
||||
void jus::GateWayClient::protocolError(const std::string& _errorHelp) {
|
||||
ejson::Object answer;
|
||||
answer.add("error", ejson::String("PROTOCOL-ERROR"));
|
||||
answer.add("error-help", ejson::String(_errorHelp));
|
||||
JUS_DEBUG("answer: " << answer.generateHumanString());
|
||||
m_interfaceClient.write(answer.generateMachineString());
|
||||
void jus::GateWayClient::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
|
||||
answerError(_transactionId, protocolError, _errorHelp);
|
||||
m_state = jus::GateWayClient::state::disconnect;
|
||||
m_interfaceClient.disconnect(true);
|
||||
}
|
||||
|
||||
void jus::GateWayClient::returnBool(int32_t _transactionId, bool _value) {
|
||||
/*
|
||||
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);
|
||||
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 jus::GateWayClient::onClientDataRaw(const jus::Buffer& _value) {
|
||||
|
||||
@ -90,7 +117,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
uint64_t transactionId = data["id"].toNumber().getU64();
|
||||
if (transactionId == 0) {
|
||||
JUS_ERROR("Protocol error ==>missing id");
|
||||
protocolError("missing parameter: 'id'");
|
||||
answerProtocolError(transactionId, "missing parameter: 'id'");
|
||||
return;
|
||||
}
|
||||
switch (m_state) {
|
||||
@ -98,13 +125,13 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
case jus::GateWayClient::state::unconnect:
|
||||
{
|
||||
JUS_ERROR("Must never appear");
|
||||
protocolError("Gateway internal error");
|
||||
answerProtocolError(transactionId, "Gateway internal error");
|
||||
return;
|
||||
}
|
||||
case jus::GateWayClient::state::connect:
|
||||
{
|
||||
if (m_userConnectionName != "") {
|
||||
protocolError("Gateway internal error 2");
|
||||
answerProtocolError(transactionId, "Gateway internal error 2");
|
||||
return;
|
||||
}
|
||||
std::string call = data["call"].toString().get();
|
||||
@ -112,46 +139,52 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
std::string mode = data["param"].toArray()[0].toString().get();
|
||||
if (mode == "JSON") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: JSON");
|
||||
m_interfaceMode = jus::connectionMode::modeJson;
|
||||
m_interfaceClient.connectCleanRaw();
|
||||
m_interfaceClient.connect(this, &jus::GateWayClient::onClientData);
|
||||
returnBool(transactionId, true);
|
||||
answerValue(transactionId, true);
|
||||
} else if (mode == "BIN") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: BINARY");
|
||||
m_interfaceMode = jus::connectionMode::modeBinary;
|
||||
m_interfaceClient.connectClean();
|
||||
m_interfaceClient.connectRaw(this, &jus::GateWayClient::onClientDataRaw);
|
||||
returnBool(transactionId, true);
|
||||
answerValue(transactionId, true);
|
||||
} else if (mode == "XML") {
|
||||
JUS_WARNING("[" << m_uid << "] Change mode in: XML");
|
||||
returnBool(transactionId, false);
|
||||
//m_interfaceMode = jus::connectionMode::modeXml;
|
||||
answerValue(transactionId, false);
|
||||
} else {
|
||||
protocolError(std::string("Call setMode with unknow argument : '") /*+ etk::to_string(int32_t(mode))*/ + "' supported [JSON/XML/BIN]");
|
||||
answerProtocolError(transactionId, std::string("Call setMode with unknow argument : '") /*+ etk::to_string(int32_t(mode))*/ + "' supported [JSON/XML/BIN]");
|
||||
}
|
||||
return;
|
||||
} else if (call == "connectToUser") {
|
||||
m_userConnectionName = data["param"].toArray()[0].toString().get();
|
||||
if (m_userConnectionName == "") {
|
||||
protocolError("Call connectToUser with no parameter 'user'");
|
||||
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) {
|
||||
protocolError("Gateway internal error 'No user interface'");
|
||||
answerProtocolError(transactionId, "Gateway internal error 'No user interface'");
|
||||
} else {
|
||||
ejson::Object linkService;
|
||||
linkService.add("event", ejson::String("new"));
|
||||
linkService.add("user", ejson::String(m_userConnectionName));
|
||||
linkService.add("client", ejson::String("**Gateway**"));
|
||||
linkService.add("groups", ejson::Array());
|
||||
linkService.add("call", ejson::String("_new"));
|
||||
linkService.add("id", ejson::Number(m_transactionLocalId++));
|
||||
ejson::Array params;
|
||||
params.add(ejson::String(m_userConnectionName));
|
||||
params.add(ejson::String("**Gateway**"));
|
||||
params.add(ejson::Array());
|
||||
linkService.add("param", params);
|
||||
m_userService->SendData(m_uid2, linkService);
|
||||
m_state = jus::GateWayClient::state::userIdentify;
|
||||
returnBool(transactionId, true);
|
||||
answerValue(transactionId, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
JUS_WARNING("[" << m_uid << "] Client must send conection to user name ...");
|
||||
protocolError("Missing call of connectToUser");
|
||||
answerProtocolError(transactionId, "Missing call of connectToUser");
|
||||
return;
|
||||
}
|
||||
case jus::GateWayClient::state::userIdentify:
|
||||
@ -164,26 +197,26 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
if ( callFunction != "identify"
|
||||
&& callFunction != "auth"
|
||||
&& callFunction != "anonymous") {
|
||||
protocolError("Client must call: identify/auth/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) {
|
||||
protocolError("gateWay internal error 3");
|
||||
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 ...");
|
||||
returnBool(transactionId, false);
|
||||
protocolError("connection refused 1");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
returnBool(transactionId, false);
|
||||
protocolError("connection refused 2");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
m_clientName = clientName;
|
||||
@ -194,12 +227,12 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
fut.wait(); // TODO: Set timeout ...
|
||||
if (fut.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
returnBool(transactionId, false);
|
||||
protocolError("connection refused 1");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 1");
|
||||
return;
|
||||
} else if (fut.get() == false) {
|
||||
returnBool(transactionId, false);
|
||||
protocolError("connection refused 2");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "connection refused 2");
|
||||
return;
|
||||
}
|
||||
m_clientName = m_userConnectionName;
|
||||
@ -214,8 +247,8 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
futGroup.wait(); // TODO: Set timeout ...
|
||||
if (futGroup.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
returnBool(transactionId, false);
|
||||
protocolError("grouping error");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "grouping error");
|
||||
return;
|
||||
}
|
||||
m_clientgroups = futGroup.get();
|
||||
@ -227,8 +260,8 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
futServices.wait(); // TODO: Set timeout ...
|
||||
if (futServices.hasError() == true) {
|
||||
JUS_ERROR("Get error from the service ...");
|
||||
returnBool(transactionId, false);
|
||||
protocolError("service filtering error");
|
||||
answerValue(transactionId, false);
|
||||
answerProtocolError(transactionId, "service filtering error");
|
||||
return;
|
||||
}
|
||||
m_clientServices = futServices.get();
|
||||
@ -237,7 +270,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
JUS_WARNING(" services: " << etk::to_string(m_clientServices));
|
||||
|
||||
|
||||
returnBool(transactionId, true);
|
||||
answerValue(transactionId, true);
|
||||
m_state = jus::GateWayClient::state::clientIdentify;
|
||||
return;
|
||||
}
|
||||
@ -250,7 +283,6 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
// This is 2 default service for the cient interface that manage the authorisation of view:
|
||||
std::string callFunction = data["call"].toString().get();
|
||||
ejson::Object answer;
|
||||
//answer.add("from-service", ejson::String(""));
|
||||
answer.add("id", data["id"]);
|
||||
if (callFunction == "getServiceCount") {
|
||||
answer.add("return", ejson::Number(m_clientServices.size()));
|
||||
@ -296,18 +328,21 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
ememory::SharedPtr<jus::GateWayService> srv = m_gatewayInterface->get(serviceName);
|
||||
if (srv != nullptr) {
|
||||
ejson::Object linkService;
|
||||
linkService.add("event", ejson::String("new"));
|
||||
linkService.add("user", ejson::String(m_userConnectionName));
|
||||
linkService.add("client", ejson::String(m_clientName));
|
||||
linkService.add("call", ejson::String("_new"));
|
||||
linkService.add("id", ejson::Number(m_transactionLocalId++));
|
||||
ejson::Array params;
|
||||
params.add(ejson::String(m_userConnectionName));
|
||||
params.add(ejson::String(m_clientName));
|
||||
// TODO ==> remove events ...
|
||||
std::vector<ActionAsyncClient> asyncAction;
|
||||
linkService.add("groups", convertToJson(asyncAction, 0, m_clientgroups));
|
||||
params.add(convertToJson(asyncAction, 0, m_clientgroups));
|
||||
linkService.add("param", params);
|
||||
if (asyncAction.size() != 0) {
|
||||
JUS_ERROR("Missing send async messages");
|
||||
}
|
||||
srv->SendData(m_uid, linkService);
|
||||
m_listConnectedService.push_back(srv);
|
||||
answer.add("return", ejson::Number(m_listConnectedService.size()-1));
|
||||
answer.add("return", ejson::Number(m_listConnectedService.size()));
|
||||
} else {
|
||||
answer.add("error", ejson::String("CAN-NOT-CONNECT-SERVICE"));
|
||||
}
|
||||
@ -321,7 +356,7 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
}
|
||||
if (callFunction == "unlink") {
|
||||
// first param:
|
||||
int64_t localServiceID = data["param"].toArray()[0].toNumber().getI64();
|
||||
int64_t localServiceID = data["param"].toArray()[0].toNumber().getI64()-1;
|
||||
// Check if service already link:
|
||||
if (localServiceID >= m_listConnectedService.size()) {
|
||||
answer.add("error", ejson::String("NOT-CONNECTED-SERVICE"));
|
||||
@ -330,8 +365,10 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
return;
|
||||
}
|
||||
ejson::Object linkService;
|
||||
// TODO : Change event in call ...
|
||||
linkService.add("event", ejson::String("delete")); // TODO : **************************************************
|
||||
linkService.add("call", ejson::String("_delete"));
|
||||
linkService.add("id", ejson::Number(m_transactionLocalId++));
|
||||
ejson::Array params;
|
||||
linkService.add("param", params);
|
||||
m_listConnectedService[localServiceID]->SendData(m_uid, linkService);
|
||||
m_listConnectedService[localServiceID] = nullptr;
|
||||
answer.add("return", ejson::Boolean(true));
|
||||
@ -346,8 +383,10 @@ void jus::GateWayClient::onClientData(std::string _value) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t serviceId = numService.getU64();
|
||||
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());
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <jus/GateWayService.h>
|
||||
#include <jus/Future.h>
|
||||
#include <jus/AbstractFunction.h>
|
||||
#include <jus/connectionMode.h>
|
||||
|
||||
|
||||
|
||||
@ -29,8 +30,10 @@ namespace jus {
|
||||
private:
|
||||
jus::GateWay* m_gatewayInterface;
|
||||
jus::TcpString m_interfaceClient;
|
||||
void protocolError(const std::string& _errorHelp);
|
||||
void returnBool(int32_t _transactionId, bool _value);
|
||||
protected:
|
||||
enum jus::connectionMode m_interfaceMode;
|
||||
public:
|
||||
enum jus::connectionMode getMode() { return m_interfaceMode; }
|
||||
public:
|
||||
esignal::Signal<bool> signalIsConnected;
|
||||
ememory::SharedPtr<jus::GateWayService> m_userService;
|
||||
@ -91,6 +94,38 @@ namespace jus {
|
||||
jus::FutureData::ObserverFinish _callback,
|
||||
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="");
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ void jus::Service::callJson(uint64_t _transactionId, const ejson::Object& _obj)
|
||||
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()
|
||||
ejson::Array params = _obj["param"].toArray();
|
||||
if (call[0] == '_') {
|
||||
if (call == "_new") {
|
||||
std::string userName = params[0].toString().get();
|
||||
@ -126,6 +126,13 @@ void jus::Service::callJson(uint64_t _transactionId, const ejson::Object& _obj)
|
||||
} else if (call == "_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());
|
||||
return;
|
||||
} else if (isFunctionAuthorized(clientId, call) == true) {
|
||||
callJson2(_transactionId, clientId, call, params);
|
||||
return;
|
||||
|
@ -48,7 +48,7 @@ jus::FutureBase jus::ServiceRemote::callJson(uint64_t _transactionId,
|
||||
}
|
||||
|
||||
jus::FutureBase jus::ServiceRemote::callBinary(uint64_t _transactionId,
|
||||
const jus::Buffer& _obj,
|
||||
jus::Buffer& _obj,
|
||||
const std::vector<ActionAsyncClient>& _async,
|
||||
jus::FutureData::ObserverFinish _callback) {
|
||||
return m_clientInterface->callBinary(_transactionId, _obj, _async, _callback, m_serviceId);
|
||||
|
@ -28,7 +28,7 @@ namespace jus {
|
||||
bool exist();
|
||||
private:
|
||||
jus::FutureBase callJson(uint64_t _transactionId, const ejson::Object& _obj, const std::vector<ActionAsyncClient>& _async, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
jus::FutureBase callBinary(uint64_t _transactionId, const jus::Buffer& _obj, const std::vector<ActionAsyncClient>& _async, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
jus::FutureBase callBinary(uint64_t _transactionId, jus::Buffer& _obj, const std::vector<ActionAsyncClient>& _async, jus::FutureData::ObserverFinish _callback=nullptr);
|
||||
uint64_t getId();
|
||||
enum jus::connectionMode getMode();
|
||||
public:
|
||||
|
@ -55,9 +55,7 @@ void jus::TcpString::threadCallback() {
|
||||
}
|
||||
} else if (m_observerRawElement != nullptr) {
|
||||
jus::Buffer data = std::move(readRaw());
|
||||
if (data.size() != 0) {
|
||||
m_observerRawElement(std::move(data));
|
||||
}
|
||||
m_observerRawElement(std::move(data));
|
||||
}
|
||||
}
|
||||
m_threadRunning = false;
|
||||
@ -136,6 +134,28 @@ int32_t jus::TcpString::write(const std::string& _data) {
|
||||
m_connection.write(&size, 4);
|
||||
return m_connection.write(_data.c_str(), _data.size());
|
||||
}
|
||||
int32_t jus::TcpString::writeBinary(const jus::Buffer& _data) {
|
||||
if (m_threadRunning == false) {
|
||||
return -2;
|
||||
}
|
||||
/*
|
||||
if (_data.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
//uint32_t size = _data.size();
|
||||
m_lastSend = std::chrono::steady_clock::now();
|
||||
const uint8_t* data = _data.getHeader();
|
||||
uint32_t dataSize = _data.getHeaderSize();
|
||||
m_connection.write(data, dataSize);
|
||||
data = _data.getParam();
|
||||
dataSize = _data.getParamSize();
|
||||
m_connection.write(data, dataSize);
|
||||
data = _data.getData();
|
||||
dataSize = _data.getDataSize();
|
||||
m_connection.write(data, dataSize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string jus::TcpString::read() {
|
||||
JUS_VERBOSE("Read [START]");
|
||||
@ -177,6 +197,45 @@ std::string jus::TcpString::read() {
|
||||
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() {
|
||||
ethread::setName("Async-sender");
|
||||
|
@ -62,6 +62,8 @@ namespace jus {
|
||||
std::string asyncRead();
|
||||
private:
|
||||
std::string read();
|
||||
jus::Buffer readRaw();
|
||||
std::vector<uint8_t> m_buffer;
|
||||
private:
|
||||
void threadCallback();
|
||||
public:
|
||||
|
@ -86,7 +86,7 @@ int main(int _argc, const char *_argv[]) {
|
||||
APPL_INFO("serviceTest1.mul = " << retCall);
|
||||
}
|
||||
*/
|
||||
if (false) {
|
||||
if (true) {
|
||||
APPL_INFO(" ----------------------------------");
|
||||
APPL_INFO(" -- Get service system-user");
|
||||
APPL_INFO(" ----------------------------------");
|
||||
@ -182,6 +182,7 @@ int main(int _argc, const char *_argv[]) {
|
||||
}
|
||||
}
|
||||
*/
|
||||
#if 0
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
jus::File tmp("./photo_2016_33913.bmp");//"image/jpg", {0,5,2,6,7,5,8,4,5,2,1,5,65,5,2,6,85,4,6,6,54,65,88,64,14,6,4,64,51,3,16,4});
|
||||
int32_t size = tmp.getData().size();
|
||||
@ -190,6 +191,7 @@ int main(int _argc, const char *_argv[]) {
|
||||
APPL_WARNING(" IO*=" << int64_t((stop-start).count()/1000)/1000.0 << " ms");
|
||||
double megaParSec = double(size)/(double((stop-start).count())/1000000000.0);
|
||||
APPL_WARNING(" speed=" << int64_t(megaParSec/1024.0)/1024.0 << " Mo/s");
|
||||
#endif
|
||||
}
|
||||
int32_t iii=0;
|
||||
while (iii < 3) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user