[DEV] get service and call element on it

This commit is contained in:
Edouard DUPIN 2016-11-30 22:09:16 +01:00
parent b13a79fe5d
commit 584f56aa29
26 changed files with 460 additions and 568 deletions

View File

@ -324,6 +324,7 @@ class ServiceDefinition:
out += "\n"
out += "#include <etk/types.hpp>\n"
out += "#include <zeus/Service.hpp>\n"
out += "#include <zeus/Client.hpp>\n"
out += "#include <" + class_name.replace("::","/") + ".hpp>\n"
out += "#include <string>\n"
out += "#include <vector>\n"
@ -343,9 +344,9 @@ class ServiceDefinition:
out += space + "void register" + self.name[-1] + "(zeus::ServiceType<" + class_name + ">& _serviceInterface);\n"
out += space + "\n"
out += space + "template<class " + MACRO_BASE_NAME + "TYPE>\n"
out += space + "zeus::Service* create" + self.name[-1] + "(std::function<ememory::SharedPtr<" + MACRO_BASE_NAME + "TYPE>(ememory::SharedPtr<ClientProperty>, const std::string& _userName)> _factory) {\n"
out += space + "zeus::Object* create" + self.name[-1] + "(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId, zeus::ServiceType<" + class_name + ">::factory _factory) {\n"
out += space + " zeus::ServiceType<" + class_name + ">* tmp = nullptr;\n"
out += space + " tmp = new zeus::ServiceType<" + class_name + ">(_factory);\n"
out += space + " tmp = new zeus::ServiceType<" + class_name + ">(_client, _objectId, _clientId, _factory);\n"
out += space + " zeus::service::register" + self.name[-1] + "(*tmp);\n"
out += space + " return tmp;\n"
out += space + "}\n"
@ -355,17 +356,21 @@ class ServiceDefinition:
out += space + "}\n"
out += space + "\n"
out += space + "#define " + MACRO_BASE_NAME + "DECLARE_DEFAULT(type) \\\n"
out += space + " ETK_EXPORT_API zeus::Service* SERVICE_IO_instanciate() { \\\n"
out += space + " return " + namespace + "create" + self.name[-1] + "<type>([](ememory::SharedPtr<zeus::ClientProperty> _client, const std::string& _userName){ \\\n"
out += space + " return ememory::makeShared<type>(_client, _userName); \\\n"
out += space + "#define " + MACRO_BASE_NAME + "DECLARE(type) \\\n"
out += space + " ETK_EXPORT_API zeus::Object* SERVICE_IO_instanciate(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId) { \\\n"
out += space + " return " + namespace + "create" + self.name[-1] + "<type>(_client, _objectId, _clientId, \\\n"
out += space + " [](uint16_t _clientId){ \\\n"
out += space + " return ememory::makeShared<type>(_clientId); \\\n"
out += space + " }); \\\n"
out += space + " }\n"
out += space + "\n"
out += space + "#define " + MACRO_BASE_NAME + "DECLARE(type, factory) \\\n"
"""
out += space + "#define " + MACRO_BASE_NAME + "DECLARE_FACTORY(type, factory) \\\n"
out += space + " ETK_EXPORT_API zeus::Service* SERVICE_IO_instanciate() { \\\n"
out += space + " return " + namespace + "create" + self.name[-1] + "<type>(factory); \\\n"
out += space + " }\n"
"""
return [filename, out]
@ -421,7 +426,7 @@ class ServiceDefinition:
_serviceInterface.propertyPort.set(_port);
}
"""
out += space + '_serviceInterface.propertyNameService.set("' + self.name[-1].lower() + '");\n'
#out += space + '_serviceInterface.propertyNameService.set("' + self.name[-1].lower() + '");\n'
if self.brief != "":
out += space + '_serviceInterface.setDescription("' + self.brief + '");\n';
if self.version != "":

View File

@ -145,7 +145,7 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO(" ----------------------------------");
APPL_INFO(" -- Get service picture");
APPL_INFO(" ----------------------------------");
if (false) {
if (true) {
zeus::service::ProxyPicture remoteServicePicture = client1.getService("picture");
if (remoteServicePicture.exist() == true) {
zeus::Future<std::vector<std::string>> retCall = remoteServicePicture.getAlbums().wait();

View File

@ -59,8 +59,8 @@ bool appl::DirectInterface::requestURI(const std::string& _uri) {
return true;
}
bool appl::DirectInterface::start(appl::GateWay* _gateway, uint16_t _id) {
appl::IOInterface::start(_gateway, _id);
bool appl::DirectInterface::start(appl::GateWay* _gateway) {
appl::IOInterface::start(_gateway, 0);
m_interfaceWeb.connect(this, &appl::DirectInterface::receive);
m_interfaceWeb.connectUri(this, &appl::DirectInterface::requestURI);
m_interfaceWeb.connect();
@ -70,7 +70,50 @@ bool appl::DirectInterface::start(appl::GateWay* _gateway, uint16_t _id) {
}
void appl::DirectInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
appl::IOInterface::receive(_value);
if (_value == nullptr) {
return;
}
// check transaction ID != 0
uint32_t transactionId = _value->getTransactionId();
if (transactionId == 0) {
APPL_ERROR("Protocol error ==>missing id");
answerProtocolError(transactionId, "missing parameter: 'id'");
return;
}
// check correct SourceID
if (_value->getSourceId() != m_uid) {
answerProtocolError(transactionId, "message with the wrong source ID");
return;
}
// Check gateway corectly connected
if (m_gateway == nullptr) {
answerProtocolError(transactionId, "GateWay error");
return;
}
// TODO: Special hook for the first call that we need to get the curretn ID of the connection, think to set this at an other position ...
if (m_uid == 0) {
APPL_INFO("special case, we need to get the ID Of the client:");
if (_value->getType() != zeus::Buffer::typeMessage::call) {
answerProtocolError(transactionId, "Must get first the Client ID... call 'getAddress'");
return;
}
ememory::SharedPtr<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_value);
if (callObj->getCall() != "getAddress") {
answerProtocolError(transactionId, "Must get first the Client ID... call 'getAddress' and not '" + callObj->getCall() + "'");
return;
}
APPL_INFO("Get the unique ID...");
m_uid = m_gateway->getId();
APPL_INFO("get ID : " << m_uid);
if (m_uid == 0) {
answerProtocolError(transactionId, "Can not get the Client ID...");
return;
}
m_interfaceWeb.setInterfaceName("cli-" + etk::to_string(m_uid));
m_interfaceWeb.answerValue(transactionId, _value->getDestination(), _value->getSource(), m_uid);
} else {
appl::IOInterface::receive(_value);
}
}
void appl::DirectInterface::send(ememory::SharedPtr<zeus::Buffer> _value) {

View File

@ -17,7 +17,7 @@ namespace appl {
public:
DirectInterface(enet::Tcp _connection);
~DirectInterface();
bool start(appl::GateWay* _gateway, uint16_t _id);
bool start(appl::GateWay* _gateway);
void receive(ememory::SharedPtr<zeus::Buffer> _data);
void send(ememory::SharedPtr<zeus::Buffer> _data);
bool requestURI(const std::string& _uri);

View File

@ -31,6 +31,7 @@ namespace appl {
m_interface.setPort(_port);
m_interface.link();
m_threadRunning = true;
APPL_INFO("Start waiting on " << _host << " " << _port);
m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr);
if (m_thread == nullptr) {
m_threadRunning = false;
@ -64,7 +65,7 @@ namespace appl {
void appl::GateWay::newService(enet::Tcp _connection) {
APPL_WARNING("New TCP connection (service)");
ememory::SharedPtr<appl::DirectInterface> tmp = ememory::makeShared<appl::DirectInterface>(std::move(_connection));
tmp->start(this, m_idIncrement++);
tmp->start(this);
m_listIODirect.push_back(tmp);
}
@ -74,8 +75,8 @@ appl::GateWay::GateWay() :
propertyRouterIp(this, "router-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp),
propertyRouterPort(this, "router-port", 1984, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort),
propertyServiceIp(this, "service-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeServiceIp),
propertyServicePort(this, "service-port", 1982, "Port to listen client", &appl::GateWay::onPropertyChangeServicePort),
propertyServiceMax(this, "service-max", 0x7FFF, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) {
propertyServicePort(this, "service-port", 1985, "Port to listen client", &appl::GateWay::onPropertyChangeServicePort),
propertyServiceMax(this, "service-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) {
m_interfaceNewService = ememory::makeShared<appl::TcpServerInput>(this);
}
@ -83,6 +84,25 @@ appl::GateWay::~GateWay() {
}
void appl::GateWay::addIO(const ememory::SharedPtr<appl::IOInterface>& _io) {
m_listIO.push_back(_io);
}
void appl::GateWay::removeIO(const ememory::SharedPtr<appl::IOInterface>& _io) {
auto it = m_listIO.begin();
while (it != m_listIO.end()) {
if (it->get() == _io.get()) {
it = m_listIO.erase(it);
} else {
++it;
}
}
}
uint16_t appl::GateWay::getId() {
return m_idIncrement++;
}
void appl::GateWay::start() {
m_routerClient = ememory::makeShared<appl::RouterInterface>(*propertyRouterIp, *propertyRouterPort, *propertyUserName, this);
@ -91,8 +111,36 @@ void appl::GateWay::start() {
void appl::GateWay::stop() {
m_routerClient.reset();
}
bool appl::GateWay::serviceExist(const std::string& _service) {
for (auto &it : m_listIO) {
if (it == nullptr) {
continue;
}
for (auto &srvIt : it->getServiceList()) {
if (srvIt == _service) {
return true;
}
}
}
return false;
}
uint16_t appl::GateWay::serviceClientIdGet(const std::string& _service) {
for (auto &it : m_listIO) {
if (it == nullptr) {
continue;
}
for (auto &srvIt : it->getServiceList()) {
if (srvIt == _service) {
return it->getId();
}
}
}
return 0;
}
/*
ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string& _serviceName) {
for (auto &it : m_serviceList) {
@ -111,27 +159,32 @@ ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string&
std::vector<std::string> appl::GateWay::getAllServiceName() {
std::vector<std::string> out;
// TODO : Change this it is old and deprecated ...
/*
for (auto &it : m_serviceList) {
for (auto &it : m_listIO) {
if (it == nullptr) {
continue;
}
out.push_back(it->getName());
for (auto &srvIt : it->getServiceList()) {
out.push_back(srvIt);
}
}
*/
return out;
}
void appl::GateWay::send(ememory::SharedPtr<zeus::Buffer> _data) {
APPL_TODO("Implement Send to a specific IO ...");
/*
if (m_routerClient != nullptr) {
m_routerClient->answer(_userSessionId, _data);
bool appl::GateWay::send(ememory::SharedPtr<zeus::Buffer> _data) {
auto it = m_listIO.begin();
uint16_t id = _data->getDestinationId();
while (it != m_listIO.end()) {
if (*it == nullptr) {
continue;
}
if ((*it)->getId() == id) {
(*it)->send(_data);
return true;
}
++it;
}
*/
return false;
}
void appl::GateWay::cleanIO() {

View File

@ -17,7 +17,6 @@ namespace appl {
private:
ememory::SharedPtr<appl::RouterInterface> m_routerClient; //!< Interface with the Gateway Front End
ememory::SharedPtr<appl::TcpServerInput> m_interfaceNewService;
public:
eproperty::Value<std::string> propertyUserName;
eproperty::Value<std::string> propertyRouterIp;
@ -28,6 +27,8 @@ namespace appl {
public:
std::vector<ememory::SharedPtr<appl::DirectInterface>> m_listIODirect; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<appl::IOInterface>> m_listIO;
void addIO(const ememory::SharedPtr<appl::IOInterface>& _io);
void removeIO(const ememory::SharedPtr<appl::IOInterface>& _io);
public:
GateWay();
@ -36,7 +37,7 @@ namespace appl {
void stop();
//ememory::SharedPtr<appl::ServiceInterface> get(const std::string& _serviceName);
std::vector<std::string> getAllServiceName();
void send(ememory::SharedPtr<zeus::Buffer> _data);
bool send(ememory::SharedPtr<zeus::Buffer> _data);
void newService(enet::Tcp _connection);
void cleanIO();
private:
@ -48,6 +49,10 @@ namespace appl {
void onPropertyChangeServiceMax();
void onClientConnect(const bool& _value);
void onServiceConnect(const bool& _value);
public:
uint16_t getId();
bool serviceExist(const std::string& _service);
uint16_t serviceClientIdGet(const std::string& _service);
};
}

View File

@ -27,6 +27,7 @@ appl::IOInterface::~IOInterface() {
APPL_INFO("---------------");
APPL_INFO("-- DELETE IO --");
APPL_INFO("---------------");
// TODO : ... m_gateway->removeIO(sharedFromThis());
}
void appl::IOInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
@ -40,12 +41,19 @@ void appl::IOInterface::answerProtocolError(uint32_t _transactionId, const std::
bool appl::IOInterface::start(appl::GateWay* _gateway, uint16_t _id) {
m_gateway = _gateway;
m_uid = _id;
m_state = appl::clientState::connect;
if (m_uid != 0) {
m_state = appl::clientState::connect;
} else {
m_state = appl::clientState::connectDirect;
}
//m_interfaceRouterClient->setInterfaceName("cli-" + etk::to_string(m_uid));
APPL_WARNING("[" << m_uid << "] New IO interface");
return true;
}
const std::vector<std::string>& appl::IOInterface::getServiceList() {
return m_listService;
}
void appl::IOInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
@ -76,6 +84,20 @@ void appl::IOInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
answerProtocolError(transactionId, "Gateway internal error");
return;
}
case appl::clientState::connectDirect:
{
if (callFunction != "service") {
answerProtocolError(transactionId, "Client must call: service");
return;
}
if (callFunction == "service") {
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
m_gateway->addIO(sharedFromThis());
m_state = appl::clientState::clientIdentify;
return;
}
}
case appl::clientState::connect:
{
/*
@ -85,8 +107,9 @@ void appl::IOInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
*/
if ( callFunction != "identify"
&& callFunction != "auth"
&& callFunction != "anonymous") {
answerProtocolError(transactionId, "Client must call: identify/auth/anonymous");
&& callFunction != "anonymous"
&& callFunction != "link") {
answerProtocolError(transactionId, "Client must call: identify/auth/anonymous/link");
return;
}
#if 0
@ -162,106 +185,130 @@ void appl::IOInterface::receive(ememory::SharedPtr<zeus::Buffer> _value) {
APPL_WARNING(" groups: " << etk::to_string(m_clientgroups));
APPL_WARNING(" services: " << etk::to_string(m_clientServices));
#endif
m_gateway->addIO(sharedFromThis());
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
m_state = appl::clientState::clientIdentify;
return;
}
if (callFunction == "link") {
// TODO : Filter services access ...
std::string serviceName = callObj->getParameter<std::string>(0);
if (m_gateway->serviceExist(serviceName) == false) {
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
uint16_t serviceClientId = m_gateway->serviceClientIdGet(serviceName);
if (serviceClientId == 0) {
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
// Replace the destination with the real owner ID
_value->setDestinationId(serviceClientId);
// Forward Call
if (m_gateway->send(_value) == false) {
zeus::WebServer* iface = getInterface();
iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "UNEXISTING-CLIENT");
}
// We do not answer, we just transmit the message to the interface that manage the service that might answer ot this call ...
return;
}
break;
case appl::clientState::clientIdentify:
{
uint32_t serviceId = callObj->getSourceId();
if (serviceId == 0) {
// This is 2 default service for the cient interface that manage the authorisation of view:
if (callFunction == "getServiceCount") {
// TODO : m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices.size());
return;
}
if (callFunction == "getServiceList") {
// TODO : m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_clientServices);
//"ServiceManager/v0.1.0"
return;
}
if (callFunction == "link") {
// first param:
std::string serviceName = callObj->getParameter<std::string>(0);
ZEUS_ERROR("Connect to service : " << serviceName << " " << m_uid);
// Check if service already link:
/*
auto it = m_listConnectedService.begin();
while (it != m_listConnectedService.end()) {
if (*it == nullptr) {
++it;
continue;
}
if ((*it)->getName() != serviceName) {
++it;
continue;
}
break;
}
if (it == m_listConnectedService.end()) {
// check if service is connectable ...
if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) {
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "UN-AUTHORIZED-SERVICE");
return;
}
ememory::SharedPtr<appl::ServiceInterface> srv = m_gatewayInterface->get(serviceName);
if (srv != nullptr) {
zeus::Future<bool> futLink = srv->m_interfaceClient.call(m_uid, ZEUS_ID_SERVICE_ROOT, "_new", m_userConnectionName, m_clientName, m_clientgroups);
futLink.wait(); // TODO: Set timeout ...
if (futLink.hasError() == true) {
APPL_ERROR("Get error from the service ... LINK");
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE");
return;
}
m_listConnectedService.push_back(srv);
ZEUS_ERROR(" ==> get ID : " << m_uid);
m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), m_listConnectedService.size());
return;
}
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "CAN-NOT-CONNECT-SERVICE");
return;
}
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "SERVICE-ALREADY-CONNECTED");;
return;
*/
}
if (callFunction == "unlink") {
ZEUS_ERROR("Disconnnect from service : " << m_uid);
// first param: the service we want to unconnect ...
/*
int64_t localServiceID = callObj->getParameter<int64_t>(0)-1;
// Check if service already link:
if (localServiceID >= m_listConnectedService.size()) {
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "NOT-CONNECTED-SERVICE");
return;
}
zeus::Future<bool> futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.call(m_uid, ZEUS_ID_SERVICE_ROOT, "_delete");
futUnLink.wait(); // TODO: Set timeout ...
if (futUnLink.hasError() == true) {
APPL_ERROR("Get error from the service ... UNLINK");
m_interfaceRouterClient->answerError(transactionId, _value->getClientId(), _value->getServiceId(), "ERROR-CREATE-SERVICE-INSTANCE");
return;
}
m_listConnectedService[localServiceID] = nullptr;
m_interfaceRouterClient->answerValue(transactionId, _value->getClientId(), _value->getServiceId(), true);
return;
*/
}
APPL_ERROR("Function does not exist ... '" << callFunction << "'");
if (callFunction == "serviceAdd") {
zeus::WebServer* iface = getInterface();
iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "CALL-UNEXISTING");
std::string serviceName = callObj->getParameter<std::string>(0);
if (serviceName == "") {
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
// Check if service exist or not:
if (m_gateway->serviceExist(serviceName) == true) {
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
ZEUS_INFO("Register new service '" << serviceName << "' in " << m_uid);
m_listService.push_back(serviceName);
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
return;
}
if (callFunction == "serviceRemove") {
zeus::WebServer* iface = getInterface();
std::string serviceName = callObj->getParameter<std::string>(0);
if (serviceName == "") {
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
}
auto it = m_listService.begin();
while (it != m_listService.end()) {
if (*it == serviceName) {
it = m_listService.erase(it);
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), true);
ZEUS_INFO("Remove new service " << serviceName << "' in " << m_uid);
return;
}
++it;
}
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
// This is 2 default service for the cient interface that manage the authorisation of view:
if (callFunction == "getServiceCount") {
// TODO : Fileter the size of accessible services
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), m_gateway->getAllServiceName().size());
return;
}
if (callFunction == "getServiceList") {
// TODO : Fileter the size of accessible services
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), m_gateway->getAllServiceName());
return;
}
if (callFunction == "link") {
// TODO : Filter services access ...
std::string serviceName = callObj->getParameter<std::string>(0);
if (m_gateway->serviceExist(serviceName) == false) {
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
uint16_t serviceClientId = m_gateway->serviceClientIdGet(serviceName);
if (serviceClientId == 0) {
zeus::WebServer* iface = getInterface();
iface->answerValue(transactionId, _value->getDestination(), _value->getSource(), false);
return;
}
// Replace the destination with the real owner ID
_value->setDestinationId(serviceClientId);
// Forward Call
if (m_gateway->send(_value) == false) {
zeus::WebServer* iface = getInterface();
iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "UNEXISTING-CLIENT");
}
// We do not answer, we just transmit the message to the interface that manage the service that might answer ot this call ...
return;
}
APPL_ERROR("Function does not exist ... '" << callFunction << "'");
zeus::WebServer* iface = getInterface();
iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "CALL-UNEXISTING");
return;
}
return;
}
}
if (m_gateway != nullptr) {
m_gateway->send(_value);
{
APPL_ERROR("UNKNOW error ... " << _value);
zeus::WebServer* iface = getInterface();
iface->answerError(transactionId, _value->getDestination(), _value->getSource(), "REQUEST-ERROR");
}
} else {
// TODO: Check here if the user is athorised to send data to a specific client ...
if (m_gateway != nullptr) {
m_gateway->send(_value);
}
}
}

View File

@ -12,15 +12,19 @@ namespace appl {
class GateWay;
enum class clientState {
unconnect, // starting sate
connect, // zeust get a TCP connection
connect, // zeus get a TCP connection (through the Router)
connectDirect, // zeus get a TCP connection 5direct connection on the gateway)
clientIdentify, // client defien the mode of the acces (anonymous,client/user)
disconnect // client is dead or loal disconnection
};
class IOInterface {
class IOInterface : public ememory::EnableSharedFromThis<appl::IOInterface> {
public:
appl::GateWay* m_gateway;
protected:
uint16_t m_uid; //!< Client unique ID (for routing)
std::vector<std::string> m_listService;
public:
const std::vector<std::string>& getServiceList();
public:
enum clientState m_state; // state machine ...
IOInterface();
@ -34,6 +38,9 @@ namespace appl {
bool checkId(uint16_t _id) const {
return m_uid == _id;
}
uint16_t getId() const {
return m_uid;
}
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
virtual zeus::WebServer* getInterface() = 0;
};

View File

@ -315,7 +315,7 @@ appl::RouterInterface::RouterInterface(const std::string& _ip, uint16_t _port, s
m_gateway(_gateway),
m_interfaceWeb() {
APPL_INFO("----------------------------------------");
APPL_INFO("-- NEW Connection to GateWay Font-end --");
APPL_INFO("-- NEW Connection to the ROUTER --");
APPL_INFO("----------------------------------------");
enet::Tcp connection = std::move(enet::connectTcpClient(_ip, _port));
if (connection.getConnectionStatus() != enet::Tcp::status::link) {
@ -325,7 +325,7 @@ appl::RouterInterface::RouterInterface(const std::string& _ip, uint16_t _port, s
m_interfaceWeb.setInterface(std::move(connection), false, _userName);
m_interfaceWeb.connect(this, &appl::RouterInterface::onClientData);
m_interfaceWeb.connect(true);
m_interfaceWeb.setInterfaceName("cli-GateWay-front-end");
m_interfaceWeb.setInterfaceName("cli-GW-to-router");
// TODO : Check if user name is accepted ...
}
@ -333,7 +333,7 @@ appl::RouterInterface::~RouterInterface() {
APPL_TODO("Call All unlink ...");
stop();
APPL_INFO("-------------------------------------------");
APPL_INFO("-- DELETE Connection to GateWay Font-end --");
APPL_INFO("-- DELETE Connection to the ROUTER --");
APPL_INFO("-------------------------------------------");
}

View File

@ -38,7 +38,7 @@ int main(int _argc, const char *_argv[]) {
APPL_PRINT(" --router-ip=XXX Router connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --router-port=XXX Router connection PORT (default: 1984)");
APPL_PRINT(" --service-ip=XXX Service connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --service-port=XXX Service connection PORT (default: 1982)");
APPL_PRINT(" --service-port=XXX Service connection PORT (default: 1985)");
APPL_PRINT(" --service-max=XXX Service Maximum IO (default: 15)");
return -1;
}

View File

@ -21,7 +21,7 @@
typedef bool (*SERVICE_IO_init_t)(int _argc, const char *_argv[], std::string _basePath);
typedef bool (*SERVICE_IO_uninit_t)();
typedef zeus::Service* (*SERVICE_IO_instanciate_t)();
typedef zeus::Object* (*SERVICE_IO_instanciate_t)(zeus::Client* _realClient, uint16_t _serviceId, uint16_t _clientId);
class PlugginAccess {
private:
@ -31,15 +31,13 @@ class PlugginAccess {
SERVICE_IO_uninit_t m_SERVICE_IO_uninit;
SERVICE_IO_instanciate_t m_SERVICE_IO_instanciate;
zeus::Client m_client;
zeus::Service* m_srv;
public:
PlugginAccess(const std::string& _name) :
m_name(_name),
m_handle(nullptr),
m_SERVICE_IO_init(nullptr),
m_SERVICE_IO_uninit(nullptr),
m_SERVICE_IO_instanciate(nullptr),
m_srv(nullptr){
m_SERVICE_IO_instanciate(nullptr) {
std::string srv = etk::FSNodeGetApplicationPath() + "/../lib/libzeus-service-" + m_name + "-impl.so";
APPL_PRINT("Try to open service with name: '" << m_name << "' at position: '" << srv << "'");
m_handle = dlopen(srv.c_str(), RTLD_LAZY);
@ -68,10 +66,7 @@ class PlugginAccess {
}
}
~PlugginAccess() {
if (m_srv != nullptr) {
delete m_srv;
m_srv = nullptr;
}
}
bool init(int _argc, const char *_argv[], std::string _basePath) {
if (m_SERVICE_IO_init == nullptr) {
@ -84,63 +79,26 @@ class PlugginAccess {
}
return (*m_SERVICE_IO_init)(_argc, _argv, _basePath);
}
bool publish(zeus::Client& _client) {
if (m_SERVICE_IO_instanciate == nullptr) {
return false;
}
_client.serviceAdd(m_name, [=](zeus::Client* _realClient, uint16_t _serviceId, uint16_t _clientId) {
ememory::SharedPtr<zeus::Object> out((*m_SERVICE_IO_instanciate)(_realClient, _serviceId, _clientId));
return out;
});
return true;
}
bool disconnect(zeus::Client& _client) {
_client.serviceRemove(m_name);
return true;
}
bool uninit() {
if (m_SERVICE_IO_uninit == nullptr) {
return false;
}
return (*m_SERVICE_IO_uninit)();
}
bool instanciate() {
if (m_SERVICE_IO_instanciate == nullptr) {
return false;
}
m_srv = (*m_SERVICE_IO_instanciate)();
return m_srv != nullptr;
}
bool connect(std::string _ip, uint16_t _port) {
if (_ip != "") {
m_client.propertyIp.set(_ip);
}
if (_port != 0) {
m_client.propertyPort.set(_port);
}
if (m_client.connect() == false) {
return false;
}
if (m_srv == nullptr) {
return false;
}
if (m_client.isAlive() == false) {
APPL_INFO("===========================================================");
APPL_INFO("== ZEUS service: " << *m_srv->propertyNameService << " [STOP] Can not connect to the GateWay");
APPL_INFO("===========================================================");
//delete m_srv;
//m_srv = nullptr;
return false;
}
return true;
}
bool ping() {
if (m_srv == nullptr) {
return false;
}
if (m_client.isAlive() == true) {
m_client.pingIsAlive();
}
return m_client.isAlive();
}
bool disconnect() {
m_client.disconnect();
if (m_srv == nullptr) {
return false;
}
APPL_INFO("===========================================================");
APPL_INFO("== ZEUS service: " << *m_srv->propertyNameService << " [STOP] GateWay Stop");
APPL_INFO("===========================================================");
return true;
}
};
@ -148,7 +106,7 @@ int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
zeus::init(_argc, _argv);
std::string ip;
uint16_t port = 0;
uint16_t port = 1985;
std::string basePath;
std::vector<std::string> services;
for (int32_t iii=0; iii<_argc ; ++iii) {
@ -167,11 +125,12 @@ int main(int _argc, const char *_argv[]) {
APPL_PRINT(" " << _argv[0] << " [options]");
APPL_PRINT(" --base-path=XXX base path to search data (default: 'USERDATA:')");
APPL_PRINT(" --ip=XXX Server connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --port=XXX Server connection PORT (default: 1983)");
APPL_PRINT(" --port=XXX Server connection PORT (default: 1985)");
APPL_PRINT(" --srv=XXX service path (N)");
return -1;
}
}
zeus::Client m_client;
std::vector<ememory::SharedPtr<PlugginAccess>> listElements;
for (auto &it: services) {
@ -182,30 +141,29 @@ int main(int _argc, const char *_argv[]) {
for (auto &it: listElements) {
it->init(_argc, _argv, basePath);
}
for (auto &it: listElements) {
it->instanciate();
if (ip != "") {
m_client.propertyIp.set(ip);
}
if (port != 0) {
m_client.propertyPort.set(port);
}
if (m_client.connect() == false) {
return -1;
}
for (auto &it: listElements) {
it->connect(ip, port);
it->publish(m_client);
}
uint32_t iii = 0;
bool oneAlive = true;
while (oneAlive == true) {
oneAlive = false;
for (auto &it: listElements) {
if (it->ping() == true) {
oneAlive = true;
}
}
if (oneAlive == true) {
std::this_thread::sleep_for(std::chrono::seconds(10));
APPL_INFO("service in waiting ... " << iii << "/inf");
iii++;
}
while(m_client.isAlive() == true) {
m_client.pingIsAlive();
std::this_thread::sleep_for(std::chrono::seconds(10));
APPL_INFO("service in waiting ... " << iii << "/inf");
iii++;
}
for (auto &it: listElements) {
it->disconnect();
it->disconnect(m_client);
}
m_client.disconnect();
APPL_INFO("Stop service*** ==> flush internal datas ...");
for (auto &it: listElements) {
it->uninit();

View File

@ -18,17 +18,17 @@ appl::GateWayInterface::GateWayInterface(enet::Tcp _connection, appl::Router* _r
m_routerInterface(_routerInterface),
m_interfaceClient(std::move(_connection), true),
m_lastSourceID(0x8000) {
ZEUS_INFO("--------------------------");
ZEUS_INFO("-- NEW GateWay Back-end --");
ZEUS_INFO("--------------------------");
ZEUS_INFO("-----------------");
ZEUS_INFO("-- NEW GateWay --");
ZEUS_INFO("-----------------");
}
appl::GateWayInterface::~GateWayInterface() {
ZEUS_INFO("------------------------------");
ZEUS_INFO("-- DELETE GateWay Back-end --");
ZEUS_INFO("------------------------------");
ZEUS_INFO("---------------------");
ZEUS_INFO("-- DELETE GateWay --");
ZEUS_INFO("---------------------");
}
bool appl::GateWayInterface::isAlive() {

View File

@ -83,10 +83,10 @@ appl::Router::Router() :
m_clientUID(2),
propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &appl::Router::onPropertyChangeClientIp),
propertyClientPort(this, "client-port", 1983, "Port to listen client", &appl::Router::onPropertyChangeClientPort),
propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &appl::Router::onPropertyChangeClientMax),
propertyGateWayIp(this, "gw-ip", "127.0.0.1", "Ip to listen client", &appl::Router::onPropertyChangeGateWayIp),
propertyGateWayPort(this, "gw-port", 1984, "Port to listen client", &appl::Router::onPropertyChangeGateWayPort),
propertyGateWayMax(this, "gw-max", 80, "Maximum of client at the same time", &appl::Router::onPropertyChangeGateWayMax) {
propertyClientMax(this, "client-max", 8000, "Maximum of client at the same time", &appl::Router::onPropertyChangeClientMax),
propertyGateWayIp(this, "gw-ip", "127.0.0.1", "Ip to listen Gateway", &appl::Router::onPropertyChangeGateWayIp),
propertyGateWayPort(this, "gw-port", 1984, "Port to listen Gateway", &appl::Router::onPropertyChangeGateWayPort),
propertyGateWayMax(this, "gw-max", 8000, "Maximum of Gateway at the same time", &appl::Router::onPropertyChangeGateWayMax) {
m_interfaceClientServer = ememory::makeShared<appl::TcpServerInput>(this, false);
m_interfaceGateWayServer = ememory::makeShared<appl::TcpServerInput>(this, true);
}

View File

@ -35,14 +35,20 @@ static uint64_t createFileID() {
namespace appl {
class PictureService : public zeus::service::Picture {
private:
//ememory::SharedPtr<zeus::ClientProperty>& m_client;
ememory::SharedPtr<zeus::ClientProperty> m_client;
std::string m_userName;
public:
PictureService(ememory::SharedPtr<zeus::ClientProperty> _client, const std::string& _userName) :
/*
PictureService(ememory::SharedPtr<zeus::ClientProperty>& _client, const std::string& _userName) :
m_client(_client),
m_userName(_userName) {
APPL_WARNING("New PictureService ... for user: ");
}
*/
PictureService(uint16_t _clientId) {
APPL_WARNING("New PictureService ... for user: ");
}
~PictureService() {
APPL_WARNING("delete PictureService ...");
}
@ -315,4 +321,17 @@ ETK_EXPORT_API bool SERVICE_IO_uninit() {
}
ZEUS_SERVICE_PICTURE_DECLARE_DEFAULT(appl::PictureService);
ZEUS_SERVICE_PICTURE_DECLARE(appl::PictureService);
/*
ETK_EXPORT_API zeus::Object* SERVICE_IO_instanciate(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId) { \
return zeus::service::createPicture<appl::PictureService>(_client, _objectId, _clientId); \
}
*/
/*
ETK_EXPORT_API zeus::Object* SERVICE_IO_instanciate(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId) { \
return zeus::service::createPicture<appl::PictureService>(_client, _objectId, _clientId, \
[](uint16_t _clientId){ \
return ememory::makeShared<appl::PictureService>(_clientId); \
}); \
}
*/

View File

@ -28,11 +28,16 @@ namespace appl {
ememory::SharedPtr<zeus::ClientProperty> m_client;
std::string m_userName;
public:
/*
SystemService(ememory::SharedPtr<zeus::ClientProperty> _client, const std::string& _userName) :
m_client(_client),
m_userName(_userName) {
APPL_WARNING("New SystemService ... for user: ");
}
*/
SystemService(uint16_t _clientId) {
APPL_WARNING("New SystemService ... for user: " << _clientId);
}
~SystemService() {
APPL_WARNING("Delete service-user interface.");
}
@ -148,11 +153,4 @@ ETK_EXPORT_API bool SERVICE_IO_uninit() {
return true;
}
#if 1
ZEUS_SERVICE_USER_DECLARE_DEFAULT(appl::SystemService);
#else
ZEUS_SERVICE_USER_DECLARE(appl::SystemService,
[](ememory::SharedPtr<zeus::ClientProperty> _client){
return ememory::makeShared<appl::SystemService>(_client);
})
#endif
ZEUS_SERVICE_USER_DECLARE(appl::SystemService);

View File

@ -38,11 +38,16 @@ namespace appl {
ememory::SharedPtr<zeus::ClientProperty> m_client;
std::string m_userName;
public:
/*
VideoService(ememory::SharedPtr<zeus::ClientProperty> _client, const std::string& _userName) :
m_client(_client),
m_userName(_userName) {
APPL_WARNING("New VideoService ... for user: ");
}
*/
VideoService(uint16_t _clientId) {
APPL_WARNING("New VideoService ... for user: ");
}
~VideoService() {
APPL_WARNING("delete VideoService ...");
}
@ -314,5 +319,5 @@ ETK_EXPORT_API bool SERVICE_IO_uninit() {
return true;
}
ZEUS_SERVICE_VIDEO_DECLARE_DEFAULT(appl::VideoService);
ZEUS_SERVICE_VIDEO_DECLARE(appl::VideoService);

View File

@ -37,6 +37,10 @@ namespace zeus {
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
ret = (*_pointer.*_func)(_obj->getParameter<ZEUS_TYPES>(idParam--)...);
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
_interfaceClient->addAsync([=](WebServer* _interface) {
_interface->answerValue(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), ret);
return true;
@ -66,6 +70,10 @@ namespace zeus {
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
(*_pointer.*_func)(_obj->getParameter<ZEUS_TYPES>(idParam--)...);
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
_interfaceClient->addAsync([=](WebServer* _interface) {
_interface->answerVoid(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource());
return true;
@ -112,6 +120,10 @@ namespace zeus {
tmpClass = (ZEUS_CLASS_TYPE*)_class;
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
// check parameter number
if (_obj->getNumberParameter() != sizeof...(ZEUS_TYPES)) {
ZEUS_ERROR("Wrong number of Parameters ...");

View File

@ -32,6 +32,10 @@ namespace zeus {
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
ret = _func(_obj->getParameter<ZEUS_TYPES>(idParam--)...);
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
_interfaceClient->addAsync([=](WebServer* _interface) {
_interface->answerValue(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), ret);
return true;
@ -59,6 +63,10 @@ namespace zeus {
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
_func(_obj->getParameter<ZEUS_TYPES>(idParam--)...);
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
_interfaceClient->addAsync([=](WebServer* _interface) {
_interface->answerVoid(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource());
return true;
@ -101,6 +109,10 @@ namespace zeus {
if (_obj == nullptr) {
return;
}
if (_interfaceClient == nullptr) {
ZEUS_ERROR("Nullptr for _interfaceWeb");
return;
}
// check parameter number
if (_obj->getNumberParameter() != sizeof...(ZEUS_TYPES)) {
std::string help = "request ";

View File

@ -70,7 +70,7 @@ void zeus::Client::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
answerProtocolError(transactionId, "interact with client, musty only call: link/unlink");
return;
}
if (callFunction != "link") {
if (callFunction == "link") {
// link with a specific service:
std::string serviceName = callObj->getParameter<std::string>(0);
for (auto &it : m_listServicesAvaillable) {
@ -81,10 +81,10 @@ void zeus::Client::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
// Create new service object
ememory::SharedPtr<zeus::Object> newService = it.second(*this, m_licalIdObjectIncrement);
ememory::SharedPtr<zeus::Object> newService = it.second(this, m_licalIdObjectIncrement, _value->getSourceId());
// TODO : Do it better ...
m_listLocalObject.push_back(newService);
m_listProvicedService.push_back(newService);
// Return the Value of the object service .... this is really bad, Maybe add a message type for this...
m_interfaceWeb->answerValue(transactionId, _value->getDestination(), _value->getSource(), (uint32_t(m_localAddress)<<16)+m_licalIdObjectIncrement );
m_licalIdObjectIncrement++;
@ -98,13 +98,22 @@ void zeus::Client::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
return;
}
// find the object to communicate the adress to send value ...
uint16_t objId = _value->getDestinationObjectId();
for (auto &it : m_listProvicedService) {
if (it == nullptr) {
continue;
}
if (it->getObjectId() == objId) {
it->receive(_value);
return;
}
}
ZEUS_ERROR("Get Data On the Communication interface that is not understand ... : " << _value);
}
bool zeus::Client::serviceAdd(const std::string& _serviceName, factoryService _factory) {
// Check if we can provide new service:
zeus::Future<bool> futValidate = m_interfaceWeb->call(m_localAddress, ZEUS_GATEWAY_ADDRESS, "serviceAdd", _serviceName);
zeus::Future<bool> futValidate = m_interfaceWeb->call(uint32_t(m_localAddress)<<16, ZEUS_GATEWAY_ADDRESS, "serviceAdd", _serviceName);
futValidate.wait(); // TODO: Set timeout ...
if (futValidate.hasError() == true) {
ZEUS_ERROR("Can not provide a new sevice ... '" << futValidate.getErrorType() << "' help:" << futValidate.getErrorHelp());
@ -116,7 +125,7 @@ bool zeus::Client::serviceAdd(const std::string& _serviceName, factoryService _f
bool zeus::Client::serviceRemove(const std::string& _serviceName) {
// Check if we can provide new service:
zeus::Future<bool> futValidate = m_interfaceWeb->call(m_localAddress, ZEUS_GATEWAY_ADDRESS, "serviceRemove", _serviceName);
zeus::Future<bool> futValidate = m_interfaceWeb->call(uint32_t(m_localAddress)<<16, ZEUS_GATEWAY_ADDRESS, "serviceRemove", _serviceName);
futValidate.wait(); // TODO: Set timeout ...
if (futValidate.hasError() == true) {
ZEUS_ERROR("Can not provide a new sevice ... '" << futValidate.getErrorType() << "' help:" << futValidate.getErrorHelp());
@ -139,7 +148,7 @@ zeus::ServiceRemote zeus::Client::getService(const std::string& _name) {
return zeus::ServiceRemote(val);
}
}
ememory::SharedPtr<zeus::ServiceRemoteBase> tmp = ememory::makeShared<zeus::ServiceRemoteBase>(m_interfaceWeb, _name);
ememory::SharedPtr<zeus::ServiceRemoteBase> tmp = ememory::makeShared<zeus::ServiceRemoteBase>(m_interfaceWeb, _name, m_localAddress, m_licalIdObjectIncrement++);
m_listConnectedService.push_back(tmp);
return zeus::ServiceRemote(tmp);
}

View File

@ -15,7 +15,6 @@
#include <zeus/Object.hpp>
namespace zeus {
class Service;
/**
* @brief Client interface to acces on the remote service and gateway
*/
@ -24,16 +23,19 @@ namespace zeus {
public:
eproperty::Value<std::string> propertyIp; //!< Ip of WebSocket TCP connection
eproperty::Value<uint16_t> propertyPort; //!< Port of the WebSocket connection
private:
public:
uint16_t m_localAddress;
uint16_t m_licalIdObjectIncrement; //!< attribute a unique ID for an object
std::string m_clientName; //!< Local client name to generate the local serrvice name if needed (if direct connection ==> no name)
ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< Interface on the Websocket interface
std::vector<ememory::WeakPtr<zeus::ServiceRemoteBase>> m_listConnectedService; //!< Connect only one time on each service, not needed more.
std::vector<ememory::SharedPtr<zeus::Service>> m_listProvicedService; //!< Connect only one time on each service, not needed more.
std::vector<ememory::SharedPtr<zeus::Object>> m_listProvicedService; //!< Connect only one time on each service, not needed more.
std::vector<ememory::SharedPtr<zeus::Object>> m_listLocalObject;
public:
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
ememory::SharedPtr<zeus::WebServer> getWebInterface() {
return m_interfaceWeb;
}
/**
* @brief
* @param[in]
@ -87,7 +89,7 @@ namespace zeus {
* @return Pointer on an interface of remote service
*/
zeus::ServiceRemote getService(const std::string& _serviceName);
using factoryService = std::function<ememory::SharedPtr<zeus::Object>(zeus::Client&, uint16_t)>;
using factoryService = std::function<ememory::SharedPtr<zeus::Object>(zeus::Client*, uint16_t, uint16_t)>; // pointer on this, object ID, client creator ID
std::map<std::string,factoryService> m_listServicesAvaillable; //!< list of all factory availlable
/**

View File

@ -8,10 +8,14 @@
#include <zeus/debug.hpp>
#include <etk/stdTools.hpp>
#include <enet/TcpClient.hpp>
#include <zeus/Client.hpp>
zeus::Object::Object() {
zeus::Object::Object(zeus::Client* _client, uint16_t _objectId) :
m_clientId(_client->m_localAddress),
m_objectId(_objectId) {
m_interfaceClient = _client->getWebInterface();
/*
zeus::AbstractFunction* func = advertise("getExtention", &zeus::Object::getExtention);
if (func != nullptr) {
@ -104,7 +108,7 @@ void zeus::Object::callBinary(ememory::SharedPtr<zeus::Buffer> _obj) {
return;
} else {
ZEUS_INFO("plop 7 ...");
m_interfaceClient->answerError(callObj->getTransactionId(), uint32_t(m_ObjectId)<<16, source, "NOT-AUTHORIZED-FUNCTION", "");
m_interfaceClient->answerError(callObj->getTransactionId(), (uint32_t(m_clientId)<<16) + m_objectId, source, "NOT-AUTHORIZED-FUNCTION", "");
return;
}
}

View File

@ -17,6 +17,7 @@
* @brief Main zeus library namespace
*/
namespace zeus {
class Client;
/**
* @brief
* @param[in]
@ -27,22 +28,24 @@ namespace zeus {
std::mutex m_mutex;
protected:
ememory::SharedPtr<zeus::WebServer> m_interfaceClient;
uint16_t m_ObjectId;
uint16_t m_clientId;
uint16_t m_objectId;
std::vector<zeus::FutureBase> m_callMultiData;
public:
uint16_t getObjectId() { return m_objectId; }
/**
* @brief
* @param[in]
* @return
*/
Object();
Object(zeus::Client* _client, uint16_t _objectId);
/**
* @brief
* @param[in]
* @return
*/
virtual ~Object();
private:
public:
/**
* @brief
* @param[in]
@ -100,6 +103,11 @@ namespace zeus {
class ObjectType : public zeus::Object {
private:
ememory::SharedPtr<ZEUS_TYPE_OBJECT> m_interface; // direct handle on the data;
public:
ObjectType(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId) :
Object(_client, _objectId) {
m_interface = ememory::makeShared<ZEUS_TYPE_OBJECT>(_clientId);
}
public:
/**
* @brief

View File

@ -8,177 +8,7 @@
#include <zeus/debug.hpp>
#include <etk/stdTools.hpp>
#include <enet/TcpClient.hpp>
#include <zeus/Client.hpp>
zeus::Service::Service() :
propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &zeus::Service::onPropertyChangeIp),
propertyPort(this, "port", 1982, "Port to connect server", &zeus::Service::onPropertyChangePort),
propertyNameService(this, "name", "no-name", "Sevice name", &zeus::Service::onPropertyChangeServiceName) {
zeus::AbstractFunction* func = advertise("getExtention", &zeus::Service::getExtention);
if (func != nullptr) {
func->setDescription("Get List of availlable extention of this service");
func->setReturn("A list of extention register in the service");
}
}
zeus::Service::~Service() {
}
std::vector<std::string> zeus::Service::getExtention() {
return std::vector<std::string>();
}
void zeus::Service::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
return;
}
ZEUS_WARNING("BUFFER" << _value);
uint32_t tmpID = _value->getTransactionId();
uint32_t source = _value->getSource();
if (_value->getType() == zeus::Buffer::typeMessage::data) {
auto it = m_callMultiData.begin();
while (it != m_callMultiData.end()) {
if ( it->getTransactionId() == tmpID
&& it->getSource() == source) {
ZEUS_WARNING("Append data ... " << tmpID);
it->appendData(_value);
if (it->isFinished() == true) {
ZEUS_WARNING("CALL Function ...");
callBinary(it->getRaw());
it = m_callMultiData.erase(it);
}
return;
}
++it;
}
ZEUS_ERROR("Un-associated data ...");
return;
}
ZEUS_WARNING("direct call");
zeus::FutureBase futData(tmpID, _value, source);
if (futData.isFinished() == true) {
ZEUS_INFO("Call Binary ..");
callBinary(futData.getRaw());
} else {
ZEUS_INFO("ADD ...");
m_callMultiData.push_back(futData);
}
}
void zeus::Service::onPropertyChangeServiceName() {
disconnect();
}
void zeus::Service::onPropertyChangeIp() {
disconnect();
}
void zeus::Service::onPropertyChangePort(){
disconnect();
}
bool zeus::Service::connect(uint32_t _numberRetry){
disconnect();
ZEUS_DEBUG("connect [START]");
enet::Tcp connection = std::move(enet::connectTcpClient(*propertyIp, *propertyPort, _numberRetry));
if (connection.getConnectionStatus() != enet::Tcp::status::link) {
ZEUS_DEBUG("connect [STOP] ==> can not connect");
return false;
}
m_interfaceClient = ememory::makeShared<zeus::WebServer>();
if (m_interfaceClient == nullptr) {
ZEUS_ERROR("Can not allocate interface ...");
return false;
}
m_interfaceClient->connect(this, &zeus::Service::onClientData);
m_interfaceClient->setInterface(std::move(connection), false, std::string("service:") + propertyNameService.get());
m_interfaceClient->connect();
if (m_interfaceClient->isActive() == false) {
ZEUS_ERROR("Can not connect service ...");
return false;
}
zeus::Future<std::string> ret = m_interfaceClient->call(ZEUS_NO_ID_CLIENT, ZEUS_ID_SERVICE_ROOT, "getUserName");
ret.wait();
m_nameUser = ret.get();
ZEUS_ERROR("Connect with name user: '" << m_nameUser << "'");
ZEUS_DEBUG("connect [STOP]");
return true;
}
void zeus::Service::disconnect(){
ZEUS_DEBUG("disconnect [START]");
if (m_interfaceClient != nullptr) {
m_interfaceClient->disconnect();
m_interfaceClient.reset();
} else {
ZEUS_VERBOSE("Nothing to disconnect ...");
}
ZEUS_DEBUG("disconnect [STOP]");
}
bool zeus::Service::GateWayAlive() {
if (m_interfaceClient == nullptr) {
return false;
}
return m_interfaceClient->isActive();
}
void zeus::Service::pingIsAlive() {
if (std::chrono::steady_clock::now() - m_interfaceClient->getLastTimeSend() >= std::chrono::seconds(30)) {
m_interfaceClient->ping();
}
}
void zeus::Service::callBinary(ememory::SharedPtr<zeus::Buffer> _obj) {
ZEUS_INFO("plop 1 ...");
if (_obj == nullptr) {
return;
}
ZEUS_INFO("plop 2 ...");
if (_obj->getType() == zeus::Buffer::typeMessage::event) {
ZEUS_ERROR("Unknow event: '...'");
return;
}
ZEUS_INFO("plop 3 ...");
if (_obj->getType() == zeus::Buffer::typeMessage::answer) {
ZEUS_ERROR("Local Answer: '...'");
return;
}
ZEUS_INFO("plop 4 ...");
if (_obj->getType() == zeus::Buffer::typeMessage::call) {
ZEUS_INFO("plop 5 ... ");
ememory::SharedPtr<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_obj);
uint32_t source = callObj->getSource();
uint32_t sourceId = callObj->getSourceId();
std::string callFunction = callObj->getCall();
ZEUS_INFO("plop - ... " << callFunction);
/*if (callFunction[0] == '_') {
if (callFunction == "_new") {
std::string userName = callObj->getParameter<std::string>(0);
std::string clientName = callObj->getParameter<std::string>(1);
std::vector<std::string> clientGroup = callObj->getParameter<std::vector<std::string>>(2);
clientConnect(sourceId, userName, clientName, clientGroup);
} else if (callFunction == "_delete") {
clientDisconnect(sourceId);
}
m_interfaceClient->answerValue(callObj->getTransactionId(), uint32_t(m_id)<<16, source, true);
return;
} else */if (isFunctionAuthorized(sourceId, callFunction) == true) {
ZEUS_INFO("plop 6 ...");
callBinary2(callFunction, callObj);
return;
} else {
ZEUS_INFO("plop 7 ...");
m_interfaceClient->answerError(callObj->getTransactionId(), uint32_t(m_id)<<16, source, "NOT-AUTHORIZED-FUNCTION", "");
return;
}
}
}

View File

@ -12,6 +12,7 @@
#include <zeus/debug.hpp>
#include <zeus/RemoteProcessCall.hpp>
#include <zeus/Future.hpp>
#include <zeus/Object.hpp>
/**
* @brief Main zeus library namespace
@ -96,159 +97,25 @@ namespace zeus {
}
namespace zeus {
/**
* @brief
* @param[in]
* @return
*/
class Service : public eproperty::Interface, public zeus::RemoteProcessCall {
protected:
std::mutex m_mutex;
public:
eproperty::Value<std::string> propertyIp; //!< Ip of WebSocket TCP connection
eproperty::Value<uint16_t> propertyPort; //!< Port of the WebSocket connection
eproperty::Value<std::string> propertyNameService; //!< Service name
protected:
ememory::SharedPtr<zeus::WebServer> m_interfaceClient;
uint32_t m_id;
std::vector<std::string> m_newData;
std::vector<zeus::FutureBase> m_callMultiData;
std::string m_nameUser;
public:
/**
* @brief
* @param[in]
* @return
*/
Service();
/**
* @brief
* @param[in]
* @return
*/
virtual ~Service();
/**
* @brief
* @param[in]
* @return true The connection is done corectly, false otherwise
*/
bool connect(uint32_t _numberRetry = 1);
/**
* @brief
* @param[in]
* @return
*/
void disconnect();
private:
/**
* @brief
* @param[in]
* @return
*/
void onClientData(ememory::SharedPtr<zeus::Buffer> _value);
public:
/**
* @brief
* @param[in]
* @return
*/
void pingIsAlive();
/**
* @brief
* @param[in]
* @return
*/
bool GateWayAlive();
private:
/**
* @brief
* @param[in]
* @return
*/
void onPropertyChangeServiceName();
/**
* @brief
* @param[in]
* @return
*/
void onPropertyChangeIp();
/**
* @brief
* @param[in]
* @return
*/
void onPropertyChangePort();
/**
* @brief A extern client connect on specific user
* @param[in] _sourceId Source session Id on the client
* @param[in] _userName User name of the client to connect
* @todo Set a relur like ==> service not availlable / service close / service maintenance / service right reject
*/
//virtual void clientConnect(uint16_t _sourceId, const std::string& _userName, const std::string& _clientName, const std::vector<std::string>& _groups) = 0;
/**
* @brief
* @param[in]
* @return
*/
//virtual void clientDisconnect(uint16_t _sourceId) = 0;
/**
* @brief
* @param[in]
* @return
*/
void callBinary(ememory::SharedPtr<zeus::Buffer> _obj);
/**
* @brief
* @param[in]
* @return
*/
virtual void callBinary2(const std::string& _call, ememory::SharedPtr<zeus::BufferCall> _obj) = 0;
/**
* @brief
* @param[in]
* @return
*/
std::vector<std::string> getExtention();
public:
/**
* @brief
* @param[in]
* @return
*/
// Add Local fuction (depend on this class)
template<class ZEUS_RETURN_VALUE,
class ZEUS_CLASS_TYPE,
class... ZEUS_FUNC_ARGS_TYPE>
zeus::AbstractFunction* advertise(std::string _name,
ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(ZEUS_FUNC_ARGS_TYPE... _args)) {
_name = "srv." + _name;
for (auto &it : m_listFunction) {
if (it == nullptr) {
continue;
}
if (it->getName() == _name) {
ZEUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'");
return nullptr;
}
}
AbstractFunction* tmp = createAbstractFunctionClass(_name, _func);
if (tmp == nullptr) {
ZEUS_ERROR("can not create abstract function ... '" << _name << "'");
return nullptr;
}
tmp->setType(zeus::AbstractFunction::type::service);
ZEUS_INFO("Add function '" << _name << "' in local mode");
m_listFunction.push_back(tmp);
return tmp;
}
};
template<class ZEUS_TYPE_SERVICE>
class ServiceType : public zeus::Service {
class ServiceType : public zeus::Object {
public:
using factory = std::function<ememory::SharedPtr<ZEUS_TYPE_SERVICE>(uint16_t)>;
private:
// no need of shared_ptr or unique_ptr (if service die all is lost and is client die, the gateway notify us...)
ememory::SharedPtr<ClientProperty> m_property;
ememory::SharedPtr<ZEUS_TYPE_SERVICE> m_interface;
public:
ServiceType(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId, factory _factory) :
Object(_client, _objectId) {
m_interface = _factory(_clientId);
}
/*
ServiceType(zeus::Client* _client, uint16_t _objectId, ememory::makeShared<ZEUS_TYPE_SERVICE> _instance) :
Object(_client, _objectId),
m_interface(_instance) {
}*/
public:
/**
* @brief
@ -399,9 +266,8 @@ namespace zeus {
}
switch (it2->getType()) {
case zeus::AbstractFunction::type::object: {
//ZEUS_TYPE_SERVICE* elem = it->second.second.get();
//it2->execute(m_interfaceClient, _obj, (void*)elem);
it2->execute(m_interfaceClient, _obj, (void*)m_interface);
ZEUS_TYPE_SERVICE* elem = m_interface.get();
it2->execute(m_interfaceClient, _obj, (void*)elem);
return;
}
case zeus::AbstractFunction::type::local: {

View File

@ -7,16 +7,20 @@
#include <zeus/ServiceRemote.hpp>
#include <zeus/Client.hpp>
zeus::ServiceRemoteBase::ServiceRemoteBase(ememory::SharedPtr<zeus::WebServer> _clientLink, const std::string& _name):
zeus::ServiceRemoteBase::ServiceRemoteBase(ememory::SharedPtr<zeus::WebServer> _clientLink, const std::string& _name, uint16_t _localId, uint16_t _localObjectId):
m_interfaceClient(_clientLink),
m_name(_name),
m_localId(_localId),
m_localObjectId(_localObjectId),
m_serviceId(0),
m_isLinked(false) {
if (m_interfaceClient == nullptr) {
return;
}
// little hack : Call the service manager with the service ID=0 ...
zeus::Future<uint32_t> ret = m_interfaceClient->call(ZEUS_NO_ID_CLIENT, m_serviceId, "link", _name);
zeus::Future<uint32_t> ret = m_interfaceClient->call((uint32_t(m_localId)<<16)+m_localObjectId, ZEUS_GATEWAY_ADDRESS, "link", _name);
ret.wait();
if (ret.hasError() == true) {
ZEUS_WARNING("Can not link with the service named: '" << _name << "' ==> link error");
@ -31,7 +35,7 @@ zeus::ServiceRemoteBase::~ServiceRemoteBase() {
uint32_t tmpLocalService = m_serviceId;
// little hack : Call the service manager with the service ID=0 ...
m_serviceId = 0;
zeus::Future<bool> ret = m_interfaceClient->call(ZEUS_NO_ID_CLIENT, m_serviceId, "unlink", tmpLocalService);
zeus::Future<bool> ret = m_interfaceClient->call((uint32_t(m_localId)<<16)+m_localObjectId, m_serviceId, "unlink", tmpLocalService);
ret.wait();
if (ret.hasError() == true) {
ZEUS_WARNING("Can not unlink with the service id: '" << tmpLocalService << "' ==> link error");

View File

@ -25,6 +25,8 @@ namespace zeus {
private:
ememory::SharedPtr<zeus::WebServer> m_interfaceClient;
std::string m_name;
uint16_t m_localId;
uint16_t m_localObjectId;
uint32_t m_serviceId;
bool m_isLinked;
public:
@ -39,7 +41,7 @@ namespace zeus {
* @param[in]
* @return
*/
ServiceRemoteBase(ememory::SharedPtr<zeus::WebServer> _clientLink, const std::string& _name);
ServiceRemoteBase(ememory::SharedPtr<zeus::WebServer> _clientLink, const std::string& _name, uint16_t _localId, uint16_t _localObjectId);
/**
* @brief
* @param[in]
@ -102,7 +104,10 @@ namespace zeus {
}
return zeus::FutureBase(0, ret);
}
return m_interface->m_interfaceClient->call(ZEUS_NO_ID_CLIENT, m_interface->m_serviceId, _functionName, _args...);
return m_interface->m_interfaceClient->call((uint32_t(m_interface->m_localId)<<16)+m_interface->m_localObjectId,
m_interface->m_serviceId,
_functionName,
_args...);
}
};