[DEV] gateway support the direct connection of client with dynamic port

This commit is contained in:
Edouard DUPIN 2017-10-14 11:23:37 +02:00
parent c11e723363
commit 27a7c404fb
9 changed files with 92 additions and 35 deletions

View File

@ -15,21 +15,30 @@
static const etk::String protocolError = "PROTOCOL-ERROR"; static const etk::String protocolError = "PROTOCOL-ERROR";
appl::DirectInterface::DirectInterface(enet::Tcp _connection) : appl::DirectInterface::DirectInterface(enet::Tcp _connection, bool _serviceAccess) :
m_interfaceWeb(etk::move(_connection), true) { m_interfaceWeb(etk::move(_connection), true),
m_serviceAccess(_serviceAccess) {
m_uid = 0; m_uid = 0;
m_state = appl::clientState::unconnect; m_state = appl::clientState::unconnect;
APPL_INFO("-----------------------"); APPL_INFO("------------------------");
APPL_INFO("-- NEW Direct Client --"); if (m_serviceAccess == true) {
APPL_INFO("-----------------------"); APPL_INFO("-- NEW SERVICE Client --");
} else {
APPL_INFO("-- NEW Direct Client --");
}
APPL_INFO("------------------------");
} }
appl::DirectInterface::~DirectInterface() { appl::DirectInterface::~DirectInterface() {
APPL_INFO("--------------------------"); APPL_INFO("---------------------------");
APPL_INFO("-- DELETE Direct Client --"); if (m_serviceAccess == true) {
APPL_INFO("--------------------------"); APPL_INFO("-- DELETE SERVICE Client --");
} else {
APPL_INFO("-- DELETE Direct Client --");
}
APPL_INFO("---------------------------");
m_interfaceWeb.disconnect(); m_interfaceWeb.disconnect();
APPL_INFO("--------------------------"); APPL_INFO("---------------------------");
} }
/* /*
void appl::clientSpecificInterface::answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp) { void appl::clientSpecificInterface::answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp) {
@ -38,12 +47,12 @@ void appl::clientSpecificInterface::answerProtocolError(uint32_t _transactionId,
m_state = appl::clientState::disconnect; m_state = appl::clientState::disconnect;
} }
*/ */
bool appl::DirectInterface::requestURI(const etk::String& _uri) { etk::String appl::DirectInterface::requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options) {
APPL_WARNING("request Direct connection: '" << _uri << "'"); APPL_WARNING("request Direct connection: '" << _uri << "'");
etk::String tmpURI = _uri; etk::String tmpURI = _uri;
if (tmpURI.size() == 0) { if (tmpURI.size() == 0) {
APPL_ERROR("Empty URI ... not supported ..."); APPL_ERROR("Empty URI ... not supported ...");
return false; return "CLOSE";
} }
if (tmpURI[0] == '/') { if (tmpURI[0] == '/') {
tmpURI = etk::String(tmpURI.begin() + 1, tmpURI.end()); tmpURI = etk::String(tmpURI.begin() + 1, tmpURI.end());
@ -51,18 +60,21 @@ bool appl::DirectInterface::requestURI(const etk::String& _uri) {
etk::Vector<etk::String> listValue = etk::split(tmpURI, '?'); etk::Vector<etk::String> listValue = etk::split(tmpURI, '?');
if (listValue.size() == 0) { if (listValue.size() == 0) {
APPL_ERROR("can not parse URI ..."); APPL_ERROR("can not parse URI ...");
return false; return "CLOSE";
} }
tmpURI = listValue[0]; tmpURI = listValue[0];
if (tmpURI == m_gateway->propertyUserName.get() ) {
return "OK";
}
if (etk::start_with(tmpURI, "directIO") == false ) { if (etk::start_with(tmpURI, "directIO") == false ) {
APPL_ERROR("Missing 'directIO:' at the start of the URI ..."); APPL_ERROR("Missing 'directIO:' at the start of the URI ...");
return false; return "CLOSE";
} }
return true; return "OK";
} }
bool appl::DirectInterface::start(appl::GateWay* _gateway) { bool appl::DirectInterface::start(appl::GateWay* _gateway) {
appl::IOInterface::start(_gateway, 0); appl::IOInterface::start(_gateway, 0, m_serviceAccess==false);
m_interfaceWeb.connect(this, &appl::DirectInterface::receive); m_interfaceWeb.connect(this, &appl::DirectInterface::receive);
m_interfaceWeb.connectUri(this, &appl::DirectInterface::requestURI); m_interfaceWeb.connectUri(this, &appl::DirectInterface::requestURI);
m_interfaceWeb.connect(); m_interfaceWeb.connect();

View File

@ -14,13 +14,14 @@ namespace appl {
class DirectInterface : public appl::IOInterface { class DirectInterface : public appl::IOInterface {
public: public:
zeus::WebServer m_interfaceWeb; zeus::WebServer m_interfaceWeb;
bool m_serviceAccess;
public: public:
DirectInterface(enet::Tcp _connection); DirectInterface(enet::Tcp _connection, bool _serviceAccess);
virtual ~DirectInterface(); virtual ~DirectInterface();
bool start(appl::GateWay* _gateway); bool start(appl::GateWay* _gateway);
void receive(ememory::SharedPtr<zeus::Message> _data); void receive(ememory::SharedPtr<zeus::Message> _data);
void send(ememory::SharedPtr<zeus::Message> _data); void send(ememory::SharedPtr<zeus::Message> _data);
bool requestURI(const etk::String& _uri); etk::String requestURI(const etk::String& _uri, const etk::Map<etk::String,etk::String>& _options);
//void answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp); //void answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp);
zeus::WebServer* getInterface() { zeus::WebServer* getInterface() {
return &m_interfaceWeb; return &m_interfaceWeb;

View File

@ -19,11 +19,13 @@ namespace appl {
ethread::Thread* m_thread; ethread::Thread* m_thread;
bool m_threadRunning; bool m_threadRunning;
appl::GateWay* m_gateway; appl::GateWay* m_gateway;
bool m_serviceAccess;
public: public:
TcpServerInput(appl::GateWay* _gateway) : TcpServerInput(appl::GateWay* _gateway, bool _serviceAccess) :
m_thread(nullptr), m_thread(nullptr),
m_threadRunning(false), m_threadRunning(false),
m_gateway(_gateway) { m_gateway(_gateway),
m_serviceAccess(_serviceAccess) {
} }
virtual ~TcpServerInput() {} virtual ~TcpServerInput() {}
@ -62,15 +64,15 @@ namespace appl {
ethread::sleepMilliSeconds((300)); ethread::sleepMilliSeconds((300));
} }
APPL_VERBOSE("New connection"); APPL_VERBOSE("New connection");
m_gateway->newDirectInterface(etk::move(data)); m_gateway->newDirectInterface(etk::move(data), m_serviceAccess);
} }
} }
}; };
} }
void appl::GateWay::newDirectInterface(enet::Tcp _connection) { void appl::GateWay::newDirectInterface(enet::Tcp _connection, bool _serviceAccess) {
APPL_WARNING("New TCP connection (service)"); APPL_WARNING("New TCP connection (service)");
ememory::SharedPtr<appl::DirectInterface> tmp = ememory::makeShared<appl::DirectInterface>(etk::move(_connection)); ememory::SharedPtr<appl::DirectInterface> tmp = ememory::makeShared<appl::DirectInterface>(etk::move(_connection), _serviceAccess);
tmp->start(this); tmp->start(this);
m_listTemporaryIO.pushBack(tmp); m_listTemporaryIO.pushBack(tmp);
} }
@ -81,11 +83,14 @@ appl::GateWay::GateWay() :
propertyRouterNo(this, "no-router", false, "No connection on the router"), propertyRouterNo(this, "no-router", false, "No connection on the router"),
propertyRouterIp(this, "router-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp), 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), propertyRouterPort(this, "router-port", 1984, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort),
propertyServiceExtern(this, "service-extern", false, "enable extern service"), propertyDirectIp(this, "direct-ip", "127.0.0.1", "Ip to listen client"),
propertyDirectPort(this, "direct-port", 0, "Port to listen direct client", &appl::GateWay::onPropertyChangeDirectClientPort),
propertyServiceExtern(this, "service-extern", true, "enable extern service"),
propertyServiceIp(this, "service-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeServiceIp), propertyServiceIp(this, "service-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeServiceIp),
propertyServicePort(this, "service-port", 1985, "Port to listen client", &appl::GateWay::onPropertyChangeServicePort), 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) { propertyServiceMax(this, "service-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) {
m_interfaceNewService = ememory::makeShared<appl::TcpServerInput>(this); m_interfaceNewService = ememory::makeShared<appl::TcpServerInput>(this, true);
m_interfaceNewClient = ememory::makeShared<appl::TcpServerInput>(this, false);
} }
appl::GateWay::~GateWay() { appl::GateWay::~GateWay() {
@ -123,13 +128,26 @@ uint16_t appl::GateWay::getId() {
void appl::GateWay::start() { void appl::GateWay::start() {
if (*propertyRouterNo == false) { if (*propertyRouterNo == false) {
m_routerClient = ememory::makeShared<appl::RouterInterface>(*propertyRouterIp, *propertyRouterPort, *propertyUserName, this); m_routerClient = ememory::makeShared<appl::RouterInterface>(propertyRouterIp.get(), propertyRouterPort.get(), propertyUserName.get(), this, propertyDirectPort.get());
if (m_routerClient->isAlive() == false) { if (m_routerClient->isAlive() == false) {
APPL_ERROR("Can not connect the Router (if it is the normal case, use option '--no-router'"); APPL_ERROR("Can not connect the Router (if it is the normal case, use option '--no-router'");
throw etk::exception::RuntimeError("Can not connect router"); throw etk::exception::RuntimeError("Can not connect router");
} }
} }
m_interfaceNewService->start(*propertyServiceIp, *propertyServicePort); // enable access of service connection (external)
if (propertyServiceExtern.get() == true) {
APPL_WARNING("#################################");
APPL_WARNING("## Open interface for Service : " << *propertyServiceIp << ":" << *propertyServicePort);
APPL_WARNING("#################################");
m_interfaceNewService->start(*propertyServiceIp, *propertyServicePort);
}
// Ebale access of direct Client
if (propertyDirectPort.get() != 0) {
APPL_WARNING("#################################");
APPL_WARNING("## Open interface for Direct client : " << *propertyDirectIp << ":" << *propertyDirectPort);
APPL_WARNING("#################################");
m_interfaceNewClient->start(*propertyDirectIp, *propertyDirectPort);
}
} }
void appl::GateWay::stop() { void appl::GateWay::stop() {
@ -300,6 +318,10 @@ void appl::GateWay::onPropertyChangeClientMax() {
} }
void appl::GateWay::onPropertyChangeDirectClientPort() {
}
void appl::GateWay::onPropertyChangeServiceIp() { void appl::GateWay::onPropertyChangeServiceIp() {
} }

View File

@ -17,11 +17,14 @@ namespace appl {
private: private:
ememory::SharedPtr<appl::RouterInterface> m_routerClient; //!< Interface with the Gateway Front End ememory::SharedPtr<appl::RouterInterface> m_routerClient; //!< Interface with the Gateway Front End
ememory::SharedPtr<appl::TcpServerInput> m_interfaceNewService; ememory::SharedPtr<appl::TcpServerInput> m_interfaceNewService;
ememory::SharedPtr<appl::TcpServerInput> m_interfaceNewClient;
public: public:
eproperty::Value<etk::String> propertyUserName; eproperty::Value<etk::String> propertyUserName;
eproperty::Value<bool> propertyRouterNo; eproperty::Value<bool> propertyRouterNo;
eproperty::Value<etk::String> propertyRouterIp; eproperty::Value<etk::String> propertyRouterIp;
eproperty::Value<uint16_t> propertyRouterPort; eproperty::Value<uint16_t> propertyRouterPort;
eproperty::Value<etk::String> propertyDirectIp;
eproperty::Value<uint16_t> propertyDirectPort;
eproperty::Value<bool> propertyServiceExtern; eproperty::Value<bool> propertyServiceExtern;
eproperty::Value<etk::String> propertyServiceIp; eproperty::Value<etk::String> propertyServiceIp;
eproperty::Value<uint16_t> propertyServicePort; eproperty::Value<uint16_t> propertyServicePort;
@ -40,12 +43,13 @@ namespace appl {
//ememory::SharedPtr<appl::ServiceInterface> get(const etk::String& _serviceName); //ememory::SharedPtr<appl::ServiceInterface> get(const etk::String& _serviceName);
etk::Vector<etk::String> getAllServiceName(); etk::Vector<etk::String> getAllServiceName();
bool send(ememory::SharedPtr<zeus::Message> _data); bool send(ememory::SharedPtr<zeus::Message> _data);
void newDirectInterface(enet::Tcp _connection); void newDirectInterface(enet::Tcp _connection, bool _serviceAccess);
void cleanIO(); void cleanIO();
private: private:
void onPropertyChangeClientIp(); void onPropertyChangeClientIp();
void onPropertyChangeClientPort(); void onPropertyChangeClientPort();
void onPropertyChangeClientMax(); void onPropertyChangeClientMax();
void onPropertyChangeDirectClientPort();
void onPropertyChangeServiceIp(); void onPropertyChangeServiceIp();
void onPropertyChangeServicePort(); void onPropertyChangeServicePort();
void onPropertyChangeServiceMax(); void onPropertyChangeServiceMax();

View File

@ -38,13 +38,17 @@ void appl::IOInterface::answerProtocolError(uint32_t _transactionId, const etk::
m_state = appl::clientState::disconnect; m_state = appl::clientState::disconnect;
} }
bool appl::IOInterface::start(appl::GateWay* _gateway, uint16_t _id) { bool appl::IOInterface::start(appl::GateWay* _gateway, uint16_t _id, bool _directClientConnection) {
m_gateway = _gateway; m_gateway = _gateway;
m_uid = _id; m_uid = _id;
if (m_uid != 0) { if (m_uid != 0) {
m_state = appl::clientState::connect; m_state = appl::clientState::connect;
} else { } else {
m_state = appl::clientState::connectDirect; if (_directClientConnection == true) {
m_state = appl::clientState::connect;
} else {
m_state = appl::clientState::connectDirect;
}
} }
//m_interfaceRouterClient->setInterfaceName("cli-" + etk::toString(m_uid)); //m_interfaceRouterClient->setInterfaceName("cli-" + etk::toString(m_uid));
APPL_WARNING("[" << m_uid << "] New IO interface"); APPL_WARNING("[" << m_uid << "] New IO interface");
@ -62,7 +66,7 @@ void appl::IOInterface::receive(ememory::SharedPtr<zeus::Message> _value) {
APPL_INFO("RECEIVE message " << _value); APPL_INFO("RECEIVE message " << _value);
uint32_t transactionId = _value->getTransactionId(); uint32_t transactionId = _value->getTransactionId();
if (transactionId == 0) { if (transactionId == 0) {
APPL_ERROR("Protocol error ==>missing id"); APPL_ERROR("Protocol error ==> missing id");
answerProtocolError(transactionId, "missing parameter: 'id'"); answerProtocolError(transactionId, "missing parameter: 'id'");
return; return;
} }

View File

@ -29,7 +29,7 @@ namespace appl {
enum clientState m_state; // state machine ... enum clientState m_state; // state machine ...
IOInterface(); IOInterface();
virtual ~IOInterface(); virtual ~IOInterface();
bool start(appl::GateWay* _gateway, uint16_t _id); bool start(appl::GateWay* _gateway, uint16_t _id, bool _directClientConnection = false);
// Data arrive from the IO // Data arrive from the IO
virtual void receive(ememory::SharedPtr<zeus::Message> _value); virtual void receive(ememory::SharedPtr<zeus::Message> _value);
// Data must be send to the IO // Data must be send to the IO

View File

@ -318,7 +318,7 @@ void appl::clientSpecificInterface::receive(ememory::SharedPtr<zeus::Message> _v
#endif #endif
appl::RouterInterface::RouterInterface(const etk::String& _ip, uint16_t _port, etk::String _userName, appl::GateWay* _gateway) : appl::RouterInterface::RouterInterface(const etk::String& _ip, uint16_t _port, etk::String _userName, appl::GateWay* _gateway, uint32_t _directPort) :
m_state(appl::clientState::unconnect), m_state(appl::clientState::unconnect),
m_gateway(_gateway), m_gateway(_gateway),
m_interfaceWeb() { m_interfaceWeb() {
@ -330,7 +330,11 @@ appl::RouterInterface::RouterInterface(const etk::String& _ip, uint16_t _port, e
APPL_ERROR("Can not connect the GateWay-front-end"); APPL_ERROR("Can not connect the GateWay-front-end");
return; return;
} }
m_interfaceWeb.setInterface(etk::move(connection), false, _userName); etk::String uri = _userName;
if (_directPort != 0) {
uri += "?directAccessPort=" + etk::toString(_directPort);
}
m_interfaceWeb.setInterface(etk::move(connection), false, uri);
m_interfaceWeb.connect(this, &appl::RouterInterface::onClientData); m_interfaceWeb.connect(this, &appl::RouterInterface::onClientData);
m_interfaceWeb.connect(true); m_interfaceWeb.connect(true);
m_interfaceWeb.setInterfaceName("cli-GW-to-router"); m_interfaceWeb.setInterfaceName("cli-GW-to-router");

View File

@ -33,7 +33,7 @@ namespace appl {
appl::GateWay* m_gateway; appl::GateWay* m_gateway;
zeus::WebServer m_interfaceWeb; zeus::WebServer m_interfaceWeb;
public: public:
RouterInterface(const etk::String& _ip, uint16_t _port, etk::String _userName, appl::GateWay* _gateway); RouterInterface(const etk::String& _ip, uint16_t _port, etk::String _userName, appl::GateWay* _gateway, uint32_t _directPort);
virtual ~RouterInterface(); virtual ~RouterInterface();
void stop(); void stop();
void onClientData(ememory::SharedPtr<zeus::Message> _value); void onClientData(ememory::SharedPtr<zeus::Message> _value);

View File

@ -50,7 +50,11 @@ class PlugginAccess {
m_SERVICE_IO_uninit(nullptr), m_SERVICE_IO_uninit(nullptr),
m_SERVICE_IO_instanciate(nullptr) { m_SERVICE_IO_instanciate(nullptr) {
etk::String srv = etk::FSNodeGetApplicationPath() + "/../lib/lib" + m_fullName + "-impl.so"; etk::String srv = etk::FSNodeGetApplicationPath() + "/../lib/lib" + m_fullName + "-impl.so";
APPL_PRINT("Try to open service with name: '" << m_name << "' at position: '" << srv << "' with full name=" << m_fullName); APPL_PRINT("++++++++++++++++++++++++++++++++");
APPL_PRINT("++ srv: '" << m_name << "' ");
APPL_PRINT("++++++++++++++++++++++++++++++++");
APPL_PRINT("At position: '" << srv << "'");
APPL_PRINT("with full name=" << m_fullName);
m_handle = dlopen(srv.c_str(), RTLD_LAZY); m_handle = dlopen(srv.c_str(), RTLD_LAZY);
if (!m_handle) { if (!m_handle) {
APPL_ERROR("Can not load Lbrary:" << dlerror()); APPL_ERROR("Can not load Lbrary:" << dlerror());
@ -150,6 +154,10 @@ int main(int _argc, const char *_argv[]) {
basicGateway.propertyRouterIp.set(etk::String(&data[12])); basicGateway.propertyRouterIp.set(etk::String(&data[12]));
} else if (etk::start_with(data, "--router-port=") == true) { } else if (etk::start_with(data, "--router-port=") == true) {
basicGateway.propertyRouterPort.set(etk::string_to_uint16_t(etk::String(&data[14]))); basicGateway.propertyRouterPort.set(etk::string_to_uint16_t(etk::String(&data[14])));
} else if (etk::start_with(data, "--direct-ip=") == true) {
basicGateway.propertyDirectIp.set(etk::String(&data[12]));
} else if (etk::start_with(data, "--direct-port=") == true) {
basicGateway.propertyDirectPort.set(etk::string_to_uint16_t(etk::String(&data[14])));
} else if (etk::start_with(data, "--router-delay=") == true) { } else if (etk::start_with(data, "--router-delay=") == true) {
int32_t value = etk::string_to_int32_t(etk::String(&data[15])); int32_t value = etk::string_to_int32_t(etk::String(&data[15]));
if (value == -1) { if (value == -1) {
@ -195,6 +203,8 @@ int main(int _argc, const char *_argv[]) {
APPL_PRINT(" --no-router Router connection disable ==> this enable the direct donnection of external client like on the router"); APPL_PRINT(" --no-router Router connection disable ==> this enable the direct donnection of external client like on the router");
APPL_PRINT(" --router-ip=XXX Router connection IP (default: " << basicGateway.propertyRouterIp.get() << ")"); APPL_PRINT(" --router-ip=XXX Router connection IP (default: " << basicGateway.propertyRouterIp.get() << ")");
APPL_PRINT(" --router-port=XXX Router connection PORT (default: " << basicGateway.propertyRouterPort.get() << ")"); APPL_PRINT(" --router-port=XXX Router connection PORT (default: " << basicGateway.propertyRouterPort.get() << ")");
APPL_PRINT(" --direct-ip=XXX Direct connection IP (default: " << basicGateway.propertyDirectIp.get() << ")");
APPL_PRINT(" --direct-port=XXX Direct connection PORT (default: " << basicGateway.propertyDirectPort.get() << " if 0 ==> not availlable)");
APPL_PRINT(" --service-extern=frue/false Disable the external service connection ==> remove open port ...(default: " << basicGateway.propertyServiceExtern.get() << ")"); APPL_PRINT(" --service-extern=frue/false Disable the external service connection ==> remove open port ...(default: " << basicGateway.propertyServiceExtern.get() << ")");
APPL_PRINT(" --service-ip=XXX Service connection IP (default: " << basicGateway.propertyServiceIp.get() << ")"); APPL_PRINT(" --service-ip=XXX Service connection IP (default: " << basicGateway.propertyServiceIp.get() << ")");
APPL_PRINT(" --service-port=XXX Service connection PORT (default: " << basicGateway.propertyServicePort.get() << ")"); APPL_PRINT(" --service-port=XXX Service connection PORT (default: " << basicGateway.propertyServicePort.get() << ")");