[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";
appl::DirectInterface::DirectInterface(enet::Tcp _connection) :
m_interfaceWeb(etk::move(_connection), true) {
appl::DirectInterface::DirectInterface(enet::Tcp _connection, bool _serviceAccess) :
m_interfaceWeb(etk::move(_connection), true),
m_serviceAccess(_serviceAccess) {
m_uid = 0;
m_state = appl::clientState::unconnect;
APPL_INFO("-----------------------");
APPL_INFO("-- NEW Direct Client --");
APPL_INFO("-----------------------");
APPL_INFO("------------------------");
if (m_serviceAccess == true) {
APPL_INFO("-- NEW SERVICE Client --");
} else {
APPL_INFO("-- NEW Direct Client --");
}
APPL_INFO("------------------------");
}
appl::DirectInterface::~DirectInterface() {
APPL_INFO("--------------------------");
APPL_INFO("-- DELETE Direct Client --");
APPL_INFO("--------------------------");
APPL_INFO("---------------------------");
if (m_serviceAccess == true) {
APPL_INFO("-- DELETE SERVICE Client --");
} else {
APPL_INFO("-- DELETE Direct Client --");
}
APPL_INFO("---------------------------");
m_interfaceWeb.disconnect();
APPL_INFO("--------------------------");
APPL_INFO("---------------------------");
}
/*
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;
}
*/
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 << "'");
etk::String tmpURI = _uri;
if (tmpURI.size() == 0) {
APPL_ERROR("Empty URI ... not supported ...");
return false;
return "CLOSE";
}
if (tmpURI[0] == '/') {
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, '?');
if (listValue.size() == 0) {
APPL_ERROR("can not parse URI ...");
return false;
return "CLOSE";
}
tmpURI = listValue[0];
if (tmpURI == m_gateway->propertyUserName.get() ) {
return "OK";
}
if (etk::start_with(tmpURI, "directIO") == false ) {
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) {
appl::IOInterface::start(_gateway, 0);
appl::IOInterface::start(_gateway, 0, m_serviceAccess==false);
m_interfaceWeb.connect(this, &appl::DirectInterface::receive);
m_interfaceWeb.connectUri(this, &appl::DirectInterface::requestURI);
m_interfaceWeb.connect();

View File

@ -14,13 +14,14 @@ namespace appl {
class DirectInterface : public appl::IOInterface {
public:
zeus::WebServer m_interfaceWeb;
bool m_serviceAccess;
public:
DirectInterface(enet::Tcp _connection);
DirectInterface(enet::Tcp _connection, bool _serviceAccess);
virtual ~DirectInterface();
bool start(appl::GateWay* _gateway);
void receive(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);
zeus::WebServer* getInterface() {
return &m_interfaceWeb;

View File

@ -19,11 +19,13 @@ namespace appl {
ethread::Thread* m_thread;
bool m_threadRunning;
appl::GateWay* m_gateway;
bool m_serviceAccess;
public:
TcpServerInput(appl::GateWay* _gateway) :
TcpServerInput(appl::GateWay* _gateway, bool _serviceAccess) :
m_thread(nullptr),
m_threadRunning(false),
m_gateway(_gateway) {
m_gateway(_gateway),
m_serviceAccess(_serviceAccess) {
}
virtual ~TcpServerInput() {}
@ -62,15 +64,15 @@ namespace appl {
ethread::sleepMilliSeconds((300));
}
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)");
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);
m_listTemporaryIO.pushBack(tmp);
}
@ -81,11 +83,14 @@ appl::GateWay::GateWay() :
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),
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),
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);
m_interfaceNewService = ememory::makeShared<appl::TcpServerInput>(this, true);
m_interfaceNewClient = ememory::makeShared<appl::TcpServerInput>(this, false);
}
appl::GateWay::~GateWay() {
@ -123,13 +128,26 @@ uint16_t appl::GateWay::getId() {
void appl::GateWay::start() {
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) {
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");
}
}
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() {
@ -300,6 +318,10 @@ void appl::GateWay::onPropertyChangeClientMax() {
}
void appl::GateWay::onPropertyChangeDirectClientPort() {
}
void appl::GateWay::onPropertyChangeServiceIp() {
}

View File

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

View File

@ -38,13 +38,17 @@ void appl::IOInterface::answerProtocolError(uint32_t _transactionId, const etk::
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_uid = _id;
if (m_uid != 0) {
m_state = appl::clientState::connect;
} 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));
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);
uint32_t transactionId = _value->getTransactionId();
if (transactionId == 0) {
APPL_ERROR("Protocol error ==>missing id");
APPL_ERROR("Protocol error ==> missing id");
answerProtocolError(transactionId, "missing parameter: 'id'");
return;
}

View File

@ -29,7 +29,7 @@ namespace appl {
enum clientState m_state; // state machine ...
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
virtual void receive(ememory::SharedPtr<zeus::Message> _value);
// Data must be send to the IO

View File

@ -318,7 +318,7 @@ void appl::clientSpecificInterface::receive(ememory::SharedPtr<zeus::Message> _v
#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_gateway(_gateway),
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");
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(true);
m_interfaceWeb.setInterfaceName("cli-GW-to-router");

View File

@ -33,7 +33,7 @@ namespace appl {
appl::GateWay* m_gateway;
zeus::WebServer m_interfaceWeb;
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();
void stop();
void onClientData(ememory::SharedPtr<zeus::Message> _value);

View File

@ -50,7 +50,11 @@ class PlugginAccess {
m_SERVICE_IO_uninit(nullptr),
m_SERVICE_IO_instanciate(nullptr) {
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);
if (!m_handle) {
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]));
} else if (etk::start_with(data, "--router-port=") == true) {
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) {
int32_t value = etk::string_to_int32_t(etk::String(&data[15]));
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(" --router-ip=XXX Router connection IP (default: " << basicGateway.propertyRouterIp.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-ip=XXX Service connection IP (default: " << basicGateway.propertyServiceIp.get() << ")");
APPL_PRINT(" --service-port=XXX Service connection PORT (default: " << basicGateway.propertyServicePort.get() << ")");