[DEV] update interface with a double gateway to permit to have a dockerisation of user service

This commit is contained in:
Edouard DUPIN 2016-11-21 22:15:46 +01:00
parent 07c58bc94f
commit 040eaf491f
26 changed files with 1039 additions and 169 deletions

View File

@ -1,5 +1,6 @@
tools/gateway-front-end
tools/gateway-back-end
tools/service-user
tools/gateway
tools/service-picture
tools/service-video
tools/player-video

70
tools/architecture.txt Normal file
View File

@ -0,0 +1,70 @@
*----------------------------------------------------------------------------*
| Docker / single binary Single User specufic program/environement |
| |
| *-----------------------* |
| +--------->| service-right-manager | |
| *-------------* | *-----------------------* |
| | |<-+ |
| | | *-----------------------* | +-------------------+
| | GATEWAY |<----------->| service-picture | | | |
+---------->| | *-----------------------* |<===>| USER X data |
| | | Back-end |<------+ | | |
| | | | | *-----------------------* | +-------------------+
| | | |<--+ +---->| service-video | |
-----------* | | | | | *-----------------------* |
| | | *-------------* | |
| | | | *-----------------------* |
| *-------------* | | +-------->| service-XXX | |
|<----* | | | | *-----------------------* |
| | | | | | |
|<----| | GATEWAY |<---+ *----------------------------------------------------------------------------*
Internet | | | |
|<----*===>|80 |
| | | |
|<----| | Front-end |<---+ *----------------------------------------------------------------------------*
| | | | | | Docker / single binary Single User specufic program/environement |
|<----* | | | | |
| *-------------* | | *-----------------------* |
| || | | +--------->| service-right-manager | |
| *----------* | | *-------------* | *-----------------------* |
-----------* | List | | | | |<-+ | +-------------------+
| of | | | | | *-----------------------* | | |
| user | | | | GATEWAY |<----------->| service-picture | |<===>| USER Y data |
|availlable| +---------->| | *-----------------------* | | |
*----------* | | Back-end |<------+ | +-------------------+
| | | | *-----------------------* |
| | |<--+ +---->| service-video | |
| | | | *-----------------------* |
| *-------------* | |
| | *-----------------------* |
| +-------->| service-XXX | |
| *-----------------------* |
| |
*----------------------------------------------------------------------------*
This is the first acces node of the service engine ==> it redirect the user to the correct gateway IP address
-----------*
|
|
| *-------------*
|<----* | |
| | | | +-------------------------+
|<----| | GATEWAY | | |
Internet | | | | | List of user |
|<----*===>| |<---->| associated gateway |
| | | | | address |
|<----| | Addressor | | |
| | | | +-------------------------+
|<----* | |
| *-------------*
|
|
-----------*

View File

@ -5,9 +5,10 @@
*/
#include <appl/debug.hpp>
#include <appl/ClientInterface.hpp>
#include <appl/ClientGateWayInterface.hpp>
#include <zeus/Future.hpp>
#include <appl/GateWay.hpp>
#include <enet/TcpClient.hpp>
#include <zeus/AbstractFunction.hpp>
@ -15,33 +16,60 @@
static const std::string protocolError = "PROTOCOL-ERROR";
appl::ClientInterface::ClientInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) :
m_state(appl::ClientInterface::state::unconnect),
appl::ClientGateWayInterface::ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface) :
m_state(appl::ClientGateWayInterface::state::unconnect),
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection), true) {
ZEUS_INFO("----------------");
ZEUS_INFO("-- NEW Client --");
ZEUS_INFO("----------------");
m_interfaceGateWayClient() {
APPL_INFO("----------------------------------------");
APPL_INFO("-- NEW Connection to GateWay Font-end --");
APPL_INFO("----------------------------------------");
enet::Tcp connection = std::move(enet::connectTcpClient(_ip, _port));
if (connection.getConnectionStatus() != enet::Tcp::status::link) {
APPL_ERROR("Can not connect the GateWay-front-end");
return;
}
m_interfaceGateWayClient.setInterface(std::move(connection), false, _userName);
m_userConnectionName = _userName;
m_state = appl::ClientGateWayInterface::state::connect;
m_interfaceGateWayClient.connect(this, &appl::ClientGateWayInterface::onClientData);
m_interfaceGateWayClient.connect(true);
m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid));
}
appl::ClientInterface::~ClientInterface() {
ZEUS_TODO("Call All unlink ...");
appl::ClientGateWayInterface::~ClientGateWayInterface() {
APPL_TODO("Call All unlink ...");
stop();
ZEUS_INFO("-------------------");
ZEUS_INFO("-- DELETE Client --");
ZEUS_INFO("-------------------");
APPL_INFO("-------------------------------------------");
APPL_INFO("-- DELETE Connection to GateWay Font-end --");
APPL_INFO("-------------------------------------------");
}
void appl::ClientInterface::start(uint64_t _uid, uint64_t _uid2) {
void appl::ClientGateWayInterface::start(uint64_t _uid, uint64_t _uid2) {
m_uid = _uid;
m_uid2 = _uid2;
m_state = appl::ClientInterface::state::connect;
m_interfaceClient.connect(this, &appl::ClientInterface::onClientData);
m_interfaceClient.connect(true);
m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid));
m_state = appl::ClientGateWayInterface::state::connect;
m_interfaceGateWayClient.setInterfaceName("cli-" + etk::to_string(m_uid));
APPL_WARNING("[" << m_uid << "] Connect to the user service");
m_userService = m_gatewayInterface->get("user");
if (m_userService == nullptr) {
//answerProtocolError(transactionId, "Gateway internal error 'No user interface'");
// TODO: Can not work at all ==> or create a fallback mode ...
}
/*
else {
zeus::Future<bool> futLocalService = m_userService->m_interfaceClient.callClient(m_uid2, "_new", m_userConnectionName, "**Gateway**", std::vector<std::string>());
futLocalService.wait(); // TODO: Set timeout ...
m_interfaceGateWayClient.answerValue(transactionId, true);
}
APPL_WARNING("[" << m_uid << "] Client must send conection to user name ...");
answerProtocolError(transactionId, "Missing call of connectToUser");
return;
}
*/
}
void appl::ClientInterface::stop() {
void appl::ClientGateWayInterface::stop() {
for (auto &it : m_listConnectedService) {
if (it == nullptr) {
continue;
@ -53,33 +81,34 @@ void appl::ClientInterface::stop() {
m_userService = nullptr;
}
m_listConnectedService.clear();
m_interfaceClient.disconnect();
m_interfaceGateWayClient.disconnect();
}
bool appl::ClientInterface::isAlive() {
return m_interfaceClient.isActive();
bool appl::ClientGateWayInterface::isAlive() {
return m_interfaceGateWayClient.isActive();
}
void appl::ClientInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp);
m_state = appl::ClientInterface::state::disconnect;
m_interfaceClient.disconnect(true);
void appl::ClientGateWayInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
m_interfaceGateWayClient.answerError(_transactionId, protocolError, _errorHelp);
m_state = appl::ClientGateWayInterface::state::disconnect;
m_interfaceGateWayClient.disconnect(true);
}
void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
void appl::ClientGateWayInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
return;
}
APPL_ERROR("get message from front-end gateWay: " << _value);
uint32_t transactionId = _value->getTransactionId();
if (transactionId == 0) {
ZEUS_ERROR("Protocol error ==>missing id");
APPL_ERROR("Protocol error ==>missing id");
answerProtocolError(transactionId, "missing parameter: 'id'");
return;
}
if (_value->getType() == zeus::Buffer::typeMessage::data) {
// TRANSMIT DATA ...
if (m_state != appl::ClientInterface::state::clientIdentify) {
if (m_state != appl::ClientGateWayInterface::state::clientIdentify) {
answerProtocolError(transactionId, "Not identify to send 'data' buffer (multiple packet element)");
return;
}
@ -90,12 +119,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
}
serviceId--;
if (serviceId >= m_listConnectedService.size()) {
m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
return;
}
if (m_listConnectedService[serviceId] == nullptr) {
// TODO ...
ZEUS_ERROR("TODO : Manage this case ...");
APPL_ERROR("TODO : Manage this case ...");
return;
}
m_listConnectedService[serviceId]->m_interfaceClient.callForwardMultiple(
@ -105,49 +134,21 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
return;
}
if (_value->getType() != zeus::Buffer::typeMessage::call) {
ZEUS_ERROR("Protocol error ==>missing 'call'");
APPL_ERROR("Protocol error ==>missing 'call'");
answerProtocolError(transactionId, "missing parameter: 'call' / wrong type 'call'");
return;
}
ememory::SharedPtr<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_value);
std::string callFunction = callObj->getCall();
switch (m_state) {
case appl::ClientInterface::state::disconnect:
case appl::ClientInterface::state::unconnect:
case appl::ClientGateWayInterface::state::disconnect:
case appl::ClientGateWayInterface::state::unconnect:
{
ZEUS_ERROR("Must never appear");
APPL_ERROR("Must never appear");
answerProtocolError(transactionId, "Gateway internal error");
return;
}
case appl::ClientInterface::state::connect:
{
if (m_userConnectionName != "") {
answerProtocolError(transactionId, "Gateway internal error 2");
return;
}
if (callFunction == "connectToUser") {
m_userConnectionName = callObj->getParameter<std::string>(0);
if (m_userConnectionName == "") {
answerProtocolError(transactionId, "Call connectToUser with no parameter 'user'");
} else {
ZEUS_WARNING("[" << m_uid << "] Set client connect to user : '" << m_userConnectionName << "'");
m_userService = m_gatewayInterface->get("system-user");
if (m_userService == nullptr) {
answerProtocolError(transactionId, "Gateway internal error 'No user interface'");
} else {
zeus::Future<bool> futLocalService = m_userService->m_interfaceClient.callClient(m_uid2, "_new", m_userConnectionName, "**Gateway**", std::vector<std::string>());
futLocalService.wait(); // TODO: Set timeout ...
m_state = appl::ClientInterface::state::userIdentify;
m_interfaceClient.answerValue(transactionId, true);
}
}
return;
}
ZEUS_WARNING("[" << m_uid << "] Client must send conection to user name ...");
answerProtocolError(transactionId, "Missing call of connectToUser");
return;
}
case appl::ClientInterface::state::userIdentify:
case appl::ClientGateWayInterface::state::connect:
{
m_clientServices.clear();
m_clientgroups.clear();
@ -169,12 +170,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
zeus::Future<bool> fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkTocken", clientName, clientTocken);
fut.wait(); // TODO: Set timeout ...
if (fut.hasError() == true) {
ZEUS_ERROR("Get error from the service ...");
m_interfaceClient.answerValue(transactionId, false);
APPL_ERROR("Get error from the service ...");
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "connection refused 1");
return;
} else if (fut.get() == false) {
m_interfaceClient.answerValue(transactionId, false);
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "connection refused 2");
return;
}
@ -185,12 +186,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
zeus::Future<bool> fut = m_userService->m_interfaceClient.callClient(m_uid2, "checkAuth", password);
fut.wait(); // TODO: Set timeout ...
if (fut.hasError() == true) {
ZEUS_ERROR("Get error from the service ...");
m_interfaceClient.answerValue(transactionId, false);
APPL_ERROR("Get error from the service ...");
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "connection refused 1");
return;
} else if (fut.get() == false) {
m_interfaceClient.answerValue(transactionId, false);
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "connection refused 2");
return;
}
@ -205,8 +206,8 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
zeus::Future<std::vector<std::string>> futGroup = m_userService->m_interfaceClient.callClient(m_uid2, "getGroups", m_clientName);
futGroup.wait(); // TODO: Set timeout ...
if (futGroup.hasError() == true) {
ZEUS_ERROR("Get error from the service ...");
m_interfaceClient.answerValue(transactionId, false);
APPL_ERROR("Get error from the service ...");
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "grouping error");
return;
}
@ -218,33 +219,33 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
zeus::Future<std::vector<std::string>> futServices = m_userService->m_interfaceClient.callClient(m_uid2, "filterServices", m_clientName, currentServices);
futServices.wait(); // TODO: Set timeout ...
if (futServices.hasError() == true) {
ZEUS_ERROR("Get error from the service ...");
m_interfaceClient.answerValue(transactionId, false);
APPL_ERROR("Get error from the service ...");
m_interfaceGateWayClient.answerValue(transactionId, false);
answerProtocolError(transactionId, "service filtering error");
return;
}
m_clientServices = futServices.get();
ZEUS_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'");
ZEUS_WARNING(" groups: " << etk::to_string(m_clientgroups));
ZEUS_WARNING(" services: " << etk::to_string(m_clientServices));
APPL_WARNING("Connection of: '" << m_clientName << "' to '" << m_userConnectionName << "'");
APPL_WARNING(" groups: " << etk::to_string(m_clientgroups));
APPL_WARNING(" services: " << etk::to_string(m_clientServices));
m_interfaceClient.answerValue(transactionId, true);
m_state = appl::ClientInterface::state::clientIdentify;
m_interfaceGateWayClient.answerValue(transactionId, true);
m_state = appl::ClientGateWayInterface::state::clientIdentify;
return;
}
break;
case appl::ClientInterface::state::clientIdentify:
case appl::ClientGateWayInterface::state::clientIdentify:
{
uint32_t serviceId = callObj->getServiceId();
if (serviceId == 0) {
// This is 2 default service for the cient interface that manage the authorisation of view:
if (callFunction == "getServiceCount") {
m_interfaceClient.answerValue(transactionId, m_clientServices.size());
m_interfaceGateWayClient.answerValue(transactionId, m_clientServices.size());
return;
}
if (callFunction == "getServiceList") {
m_interfaceClient.answerValue(transactionId, m_clientServices);
m_interfaceGateWayClient.answerValue(transactionId, m_clientServices);
//"ServiceManager/v0.1.0"
return;
}
@ -267,7 +268,7 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
if (it == m_listConnectedService.end()) {
// check if service is connectable ...
if (std::find(m_clientServices.begin(), m_clientServices.end(), serviceName) == m_clientServices.end()) {
m_interfaceClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE");
m_interfaceGateWayClient.answerError(transactionId, "UN-AUTHORIZED-SERVICE");
return;
}
ememory::SharedPtr<appl::ServiceInterface> srv = m_gatewayInterface->get(serviceName);
@ -275,18 +276,18 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
zeus::Future<bool> futLink = srv->m_interfaceClient.callClient(m_uid, "_new", m_userConnectionName, m_clientName, m_clientgroups);
futLink.wait(); // TODO: Set timeout ...
if (futLink.hasError() == true) {
ZEUS_ERROR("Get error from the service ... LINK");
m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
APPL_ERROR("Get error from the service ... LINK");
m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
return;
}
m_listConnectedService.push_back(srv);
m_interfaceClient.answerValue(transactionId, m_listConnectedService.size());
m_interfaceGateWayClient.answerValue(transactionId, m_listConnectedService.size());
return;
}
m_interfaceClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE");
m_interfaceGateWayClient.answerError(transactionId, "CAN-NOT-CONNECT-SERVICE");
return;
}
m_interfaceClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");;
m_interfaceGateWayClient.answerError(transactionId, "SERVICE-ALREADY-CONNECTED");;
return;
}
if (callFunction == "unlink") {
@ -294,33 +295,33 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
int64_t localServiceID = callObj->getParameter<int64_t>(0)-1;
// Check if service already link:
if (localServiceID >= m_listConnectedService.size()) {
m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
return;
}
zeus::Future<bool> futUnLink = m_listConnectedService[localServiceID]->m_interfaceClient.callClient(m_uid, "_delete");
futUnLink.wait(); // TODO: Set timeout ...
if (futUnLink.hasError() == true) {
ZEUS_ERROR("Get error from the service ... UNLINK");
m_interfaceClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
APPL_ERROR("Get error from the service ... UNLINK");
m_interfaceGateWayClient.answerError(transactionId, "ERROR-CREATE-SERVICE-INSTANCE");
return;
}
m_listConnectedService[localServiceID] = nullptr;
m_interfaceClient.answerValue(transactionId, true);
m_interfaceGateWayClient.answerValue(transactionId, true);
return;
}
ZEUS_ERROR("Function does not exist ... '" << callFunction << "'");
m_interfaceClient.answerError(transactionId, "CALL-UNEXISTING");
APPL_ERROR("Function does not exist ... '" << callFunction << "'");
m_interfaceGateWayClient.answerError(transactionId, "CALL-UNEXISTING");
return;
}
// decrease service ID ...
serviceId -= 1;
if (serviceId >= m_listConnectedService.size()) {
m_interfaceClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
m_interfaceGateWayClient.answerError(transactionId, "NOT-CONNECTED-SERVICE");
return;
} else {
if (m_listConnectedService[serviceId] == nullptr) {
// TODO ...
ZEUS_ERROR("TODO : Manage this case ...");
APPL_ERROR("TODO : Manage this case ...");
return;
}
m_listConnectedService[serviceId]->m_interfaceClient.callForward(
@ -332,12 +333,12 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
if (tmpp == nullptr) {
return true;
}
ZEUS_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId);
ZEUS_DEBUG(" msg=" << tmpp);
APPL_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId);
APPL_DEBUG(" msg=" << tmpp);
tmpp->setTransactionId(transactionId);
tmpp->setServiceId(serviceId+1);
ZEUS_DEBUG("transmit=" << tmpp);
m_interfaceClient.writeBinary(tmpp);
APPL_DEBUG("transmit=" << tmpp);
m_interfaceGateWayClient.writeBinary(tmpp);
// multiple send element ...
return tmpp->getPartFinish();
});
@ -346,6 +347,6 @@ void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value
}
}
void appl::ClientInterface::returnMessage(ememory::SharedPtr<zeus::Buffer> _data) {
ZEUS_ERROR("Get call from the Service to the user ...");
void appl::ClientGateWayInterface::returnMessage(ememory::SharedPtr<zeus::Buffer> _data) {
APPL_ERROR("Get call from the Service to the user ...");
}

View File

@ -0,0 +1,53 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <zeus/WebServer.hpp>
#include <appl/GateWay.hpp>
#include <appl/ServiceInterface.hpp>
namespace appl {
class GateWay;
class ClientGateWayInterface {
private:
enum class state {
unconnect, // starting sate
connect, // zeust get a TCP connection
clientIdentify, // client defien the mode of the acces (anonymous,client/user)
disconnect // client is dead or loal disconnection
};
enum state m_state; // state machine ...
private:
appl::GateWay* m_gatewayInterface;
zeus::WebServer m_interfaceGateWayClient;
public:
ememory::SharedPtr<appl::ServiceInterface> m_userService;
std::vector<ememory::SharedPtr<appl::ServiceInterface>> m_listConnectedService;
uint64_t m_uid;
uint64_t m_uid2;
std::string m_userConnectionName;
std::string m_clientName;
std::vector<std::string> m_clientgroups;
std::vector<std::string> m_clientServices;
public:
ClientGateWayInterface(const std::string& _ip, uint16_t _port, const std::string& _userName, appl::GateWay* _gatewayInterface);
virtual ~ClientGateWayInterface();
void start(uint64_t _uid, uint64_t _uid2);
void stop();
void onClientData(ememory::SharedPtr<zeus::Buffer> _value);
void returnMessage(ememory::SharedPtr<zeus::Buffer> _data);
bool checkId(uint64_t _id) const {
return m_uid == _id
|| m_uid2 == _id;
}
bool isAlive();
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
};
}

View File

@ -0,0 +1,196 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/GateWay.hpp>
#include <appl/debug.hpp>
#include <enet/TcpServer.hpp>
namespace appl {
class TcpServerInput {
private:
enet::TcpServer m_interface;
std::thread* m_thread;
bool m_threadRunning;
appl::GateWay* m_gateway;
public:
TcpServerInput(appl::GateWay* _gateway) :
m_thread(nullptr),
m_threadRunning(false),
m_gateway(_gateway) {
}
virtual ~TcpServerInput() {}
void start(const std::string& _host, uint16_t _port) {
m_interface.setHostNane(_host);
m_interface.setPort(_port);
m_interface.link();
m_threadRunning = true;
m_thread = new std::thread([&](void *){ this->threadCallback();}, nullptr);
if (m_thread == nullptr) {
m_threadRunning = false;
APPL_ERROR("creating callback thread!");
return;
}
}
void stop() {
if (m_thread != nullptr) {
m_threadRunning = false;
}
m_interface.unlink();
if (m_thread != nullptr) {
m_thread->join();
delete m_thread;
m_thread = nullptr;
}
}
void threadCallback() {
// get datas:
while (m_threadRunning == true) {
// READ section data:
enet::Tcp data = std::move(m_interface.waitNext());
APPL_VERBOSE("New connection");
m_gateway->newService(std::move(data));
}
}
};
}
void appl::GateWay::newService(enet::Tcp _connection) {
APPL_WARNING("New TCP connection (service)");
ememory::SharedPtr<appl::ServiceInterface> tmp = ememory::makeShared<appl::ServiceInterface>(std::move(_connection), this);
tmp->start();
m_serviceList.push_back(tmp);
}
appl::GateWay::GateWay() :
m_clientUID(1),
propertyUserName(this, "user", "no-name", "User name of the interface"), // must be set befor start ...
propertyGateWayClientIp(this, "gw-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp),
propertyGateWayClientPort(this, "gw-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", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) {
m_interfaceServiceServer = ememory::makeShared<appl::TcpServerInput>(this);
}
appl::GateWay::~GateWay() {
}
void appl::GateWay::start() {
m_gateWayClient = ememory::makeShared<appl::ClientGateWayInterface>(*propertyGateWayClientIp, *propertyGateWayClientPort, *propertyUserName, this);
m_interfaceServiceServer->start(*propertyServiceIp, *propertyServicePort);
}
void appl::GateWay::stop() {
m_gateWayClient.reset();
}
ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string& _serviceName) {
for (auto &it : m_serviceList) {
if (it == nullptr) {
continue;
}
if (it->getName() != _serviceName) {
continue;
}
return it;
}
return nullptr;
}
std::vector<std::string> appl::GateWay::getAllServiceName() {
std::vector<std::string> out;
for (auto &it : m_serviceList) {
if (it == nullptr) {
continue;
}
out.push_back(it->getName());
}
return out;
}
void appl::GateWay::answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data) {
/*
for (auto &it : m_gateWayClient) {
if (it == nullptr) {
continue;
}
if (it->checkId(_userSessionId) == false) {
continue;
}
it->returnMessage(_data);
return;
}
*/
}
void appl::GateWay::cleanIO() {
auto it = m_serviceList.begin();
while (it != m_serviceList.end()) {
if (*it != nullptr) {
if ((*it)->isAlive() == false) {
it = m_serviceList.erase(it);
continue;
}
} else {
it = m_serviceList.erase(it);
continue;
}
++it;
}
/*
auto it2 = m_gateWayClient.begin();
while (it2 != m_gateWayClient.end()) {
if (*it2 != nullptr) {
if ((*it2)->isAlive() == false) {
it2 = m_gateWayClient.erase(it2);
continue;
}
} else {
it2 = m_gateWayClient.erase(it2);
continue;
}
++it2;
}
*/
}
void appl::GateWay::onClientConnect(const bool& _value) {
APPL_TODO("Client connection: " << _value);
}
void appl::GateWay::onServiceConnect(const bool& _value) {
APPL_TODO("Service connection: " << _value);
}
void appl::GateWay::onPropertyChangeClientIp() {
}
void appl::GateWay::onPropertyChangeClientPort() {
}
void appl::GateWay::onPropertyChangeClientMax() {
}
void appl::GateWay::onPropertyChangeServiceIp() {
}
void appl::GateWay::onPropertyChangeServicePort() {
}
void appl::GateWay::onPropertyChangeServiceMax() {
}

View File

@ -5,7 +5,7 @@
*/
#pragma once
#include <appl/ServiceInterface.hpp>
#include <appl/ClientInterface.hpp>
#include <appl/ClientGateWayInterface.hpp>
#include <eproperty/Value.hpp>
namespace appl {
@ -15,14 +15,13 @@ namespace appl {
uint64_t m_clientUID;
private:
std::vector<ememory::SharedPtr<appl::ServiceInterface>> m_serviceList; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<appl::ClientInterface>> m_clientList; //!< List of all Client interface with their own connection
//TODO: std::vector<appl::ServerInterface> m_ServerList; //!< List of all Server connected to this gateway
ememory::SharedPtr<appl::TcpServerInput> m_interfaceClientServer;
ememory::SharedPtr<appl::ClientGateWayInterface> m_gateWayClient; //!< Interface with the Gateway Front End
ememory::SharedPtr<appl::TcpServerInput> m_interfaceServiceServer;
public:
eproperty::Value<std::string> propertyClientIp;
eproperty::Value<uint16_t> propertyClientPort;
eproperty::Value<uint16_t> propertyClientMax;
eproperty::Value<std::string> propertyUserName;
eproperty::Value<std::string> propertyGateWayClientIp;
eproperty::Value<uint16_t> propertyGateWayClientPort;
eproperty::Value<std::string> propertyServiceIp;
eproperty::Value<uint16_t> propertyServicePort;
eproperty::Value<uint16_t> propertyServiceMax;
@ -35,7 +34,6 @@ namespace appl {
std::vector<std::string> getAllServiceName();
void answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data);
void newService(enet::Tcp _connection);
void newClient(enet::Tcp _connection);
void cleanIO();
private:
void onPropertyChangeClientIp();

View File

@ -6,7 +6,7 @@
#include <appl/debug.hpp>
#include <appl/ServiceInterface.hpp>
#include <appl/ClientInterface.hpp>
#include <appl/ClientGateWayInterface.hpp>
#include <appl/GateWay.hpp>
// todo : cHANGE THIS ...
@ -17,16 +17,16 @@ static const std::string protocolError = "PROTOCOL-ERROR";
appl::ServiceInterface::ServiceInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection), true) {
ZEUS_INFO("-----------------");
ZEUS_INFO("-- NEW Service --");
ZEUS_INFO("-----------------");
APPL_INFO("-----------------");
APPL_INFO("-- NEW Service --");
APPL_INFO("-----------------");
}
appl::ServiceInterface::~ServiceInterface() {
ZEUS_INFO("--------------------");
ZEUS_INFO("-- DELETE Service --");
ZEUS_INFO("--------------------");
APPL_INFO("--------------------");
APPL_INFO("-- DELETE Service --");
APPL_INFO("--------------------");
}
bool appl::ServiceInterface::isAlive() {
@ -60,14 +60,14 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr<zeus::Buffer> _val
if (data.valueExist("event") == true) {
// No need to have a user ID ...
if (data["event"].toString().get() == "IS-ALIVE") {
ZEUS_VERBOSE("Service Alive ...");
APPL_VERBOSE("Service Alive ...");
if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(20)) {
ejson::Object tmpp;
tmpp.add("event", ejson::String("IS-ALIVE"));
m_interfaceClient.writeJson(tmpp);
}
} else {
ZEUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
APPL_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
}
return;
}
@ -79,7 +79,7 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr<zeus::Buffer> _val
std::string callFunction = callObj->getCall();
if (callFunction == "connect-service") {
if (m_name != "") {
ZEUS_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter<std::string>(0));
APPL_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter<std::string>(0));
m_interfaceClient.answerValue(transactionId, false);
return;
}
@ -91,7 +91,7 @@ void appl::ServiceInterface::onServiceData(ememory::SharedPtr<zeus::Buffer> _val
answerProtocolError(transactionId, "unknow function");
}
if (_value->getClientId() == 0) {
ZEUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'");
APPL_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'");
return;
}
m_gatewayInterface->answer(_value->getClientId(), _value);

View File

@ -10,9 +10,9 @@
namespace appl {
class GateWay;
class ClientInterface;
class ClientGateWayInterface;
class ServiceInterface {
friend class appl::ClientInterface;
friend class appl::ClientGateWayInterface;
private:
appl::GateWay* m_gatewayInterface;
zeus::WebServer m_interfaceClient;

View File

@ -18,12 +18,12 @@ int main(int _argc, const char *_argv[]) {
appl::GateWay basicGateway;
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if (etk::start_with(data, "--client-ip=") == true) {
basicGateway.propertyClientIp.set(std::string(&data[12]));
} else if (etk::start_with(data, "--client-port=") == true) {
basicGateway.propertyClientPort.set(etk::string_to_uint16_t(std::string(&data[14])));
} else if (etk::start_with(data, "--client-max=") == true) {
basicGateway.propertyClientMax.set(etk::string_to_uint16_t(std::string(&data[13])));
if (etk::start_with(data, "--user=") == true) {
basicGateway.propertyUserName.set(std::string(&data[7]));
} else if (etk::start_with(data, "--gw-ip=") == true) {
basicGateway.propertyGateWayClientIp.set(std::string(&data[8]));
} else if (etk::start_with(data, "--gw-port=") == true) {
basicGateway.propertyGateWayClientPort.set(etk::string_to_uint16_t(std::string(&data[10])));
} else if (etk::start_with(data, "--service-ip=") == true) {
basicGateway.propertyServiceIp.set(std::string(&data[13]));
} else if (etk::start_with(data, "--service-port=") == true) {
@ -34,11 +34,11 @@ int main(int _argc, const char *_argv[]) {
|| data == "--help") {
APPL_PRINT(etk::getApplicationName() << " - help : ");
APPL_PRINT(" " << _argv[0] << " [options]");
APPL_PRINT(" --client-ip=XXX Client connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --client-port=XXX Client connection PORT (default: 1983)");
APPL_PRINT(" --client-max=XXX Clainet Maximum parallele connection (default: 80)");
APPL_PRINT(" --user=XXX Name of the user that we are connected.");
APPL_PRINT(" --gw-ip=XXX GateWay Front-end connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --gw-port=XXX GateWay Front-end 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: 1984)");
APPL_PRINT(" --service-port=XXX Service connection PORT (default: 1982)");
APPL_PRINT(" --service-max=XXX Service Maximum IO (default: 15)");
return -1;
}

View File

@ -29,7 +29,7 @@ def configure(target, my_module):
my_module.add_depend(['zeus'])
my_module.add_src_file([
'appl/debug.cpp',
'appl/ClientInterface.cpp',
'appl/ClientGateWayInterface.cpp',
'appl/ServiceInterface.cpp',
'appl/GateWay.cpp',
'appl/main.cpp'

View File

@ -0,0 +1,148 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/ClientInterface.hpp>
#include <zeus/Future.hpp>
#include <appl/GateWay.hpp>
#include <zeus/AbstractFunction.hpp>
static const std::string protocolError = "PROTOCOL-ERROR";
appl::ClientInterface::ClientInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) :
m_state(appl::ClientInterface::state::unconnect),
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection), true) {
APPL_INFO("----------------");
APPL_INFO("-- NEW Client --");
APPL_INFO("----------------");
}
appl::ClientInterface::~ClientInterface() {
APPL_INFO("Call All unlink ...");
stop();
APPL_INFO("-------------------");
APPL_INFO("-- DELETE Client --");
APPL_INFO("-------------------");
}
bool appl::ClientInterface::requestURI(const std::string& _uri) {
APPL_WARNING("request connect on CLIENT: '" << _uri << "'");
if(m_gatewayInterface == nullptr) {
APPL_ERROR("Can not access to the main GateWay interface (nullptr)");
return false;
}
std::string tmpURI = _uri;
if (tmpURI.size() == 0) {
APPL_ERROR("Empty URI ... not supported ...");
return false;
}
if (tmpURI[0] == '/') {
tmpURI = std::string(tmpURI.begin() + 1, tmpURI.end());
}
// TODO : Remove subParameters xxx?YYY
m_userGateWay = m_gatewayInterface->get(tmpURI);
if (m_userGateWay == nullptr) {
APPL_ERROR("Can not connect on Client ==> it does not exist ...");
return false;
}
APPL_INFO("Connect on client done : '" << tmpURI << "'");
return true;
}
void appl::ClientInterface::start(uint64_t _uid, uint64_t _uid2) {
m_uid = _uid;
//m_uid2 = _uid2;
m_state = appl::ClientInterface::state::connect;
m_interfaceClient.connect(this, &appl::ClientInterface::onClientData);
m_interfaceClient.connectUri(this, &appl::ClientInterface::requestURI);
m_interfaceClient.connect(true);
m_interfaceClient.setInterfaceName("cli-" + etk::to_string(m_uid));
}
void appl::ClientInterface::stop() {
for (auto &it : m_listConnectedService) {
if (it == nullptr) {
continue;
}
it->m_interfaceClient.callClient(m_uid, "_delete");
}
/*
if (m_userGateWay != nullptr) {
m_userGateWay->m_interfaceClient.callClient(m_uid2, "_delete");
m_userGateWay = nullptr;
}
*/
m_listConnectedService.clear();
m_interfaceClient.disconnect();
}
bool appl::ClientInterface::isAlive() {
return m_interfaceClient.isActive();
}
void appl::ClientInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp);
m_state = appl::ClientInterface::state::disconnect;
m_interfaceClient.disconnect(true);
}
void appl::ClientInterface::onClientData(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
return;
}
APPL_ERROR("receive data : " << _value);
uint32_t transactionId = _value->getTransactionId();
if (transactionId == 0) {
APPL_ERROR("Protocol error ==>missing id");
answerProtocolError(transactionId, "missing parameter: 'id'");
return;
}
// Directly send to the user-GateWay
if (m_userGateWay == nullptr) {
APPL_ERROR("USER is not existing ...");
answerProtocolError(transactionId, "GateWay error");
// TODO : Need to kill socket ...
return;
}
// Special case for data, they are transiting messages ...
if (_value->getType() != zeus::Buffer::typeMessage::data) {
m_userGateWay->m_interfaceClient.callForward(
m_uid,
_value,
(uint64_t(m_uid) << 32) + uint64_t(transactionId),
[=](zeus::FutureBase _ret) {
ememory::SharedPtr<zeus::Buffer> tmpp = _ret.getRaw();
if (tmpp == nullptr) {
return true;
}
APPL_DEBUG(" ==> transmit : " << tmpp->getTransactionId() << " -> " << transactionId);
APPL_DEBUG(" msg=" << tmpp);
tmpp->setTransactionId(transactionId);
//tmpp->setServiceId(serviceId+1);
APPL_DEBUG("transmit=" << tmpp);
m_interfaceClient.writeBinary(tmpp);
// multiple send element ...
return tmpp->getPartFinish();
});
} else {
// simply forward messages to the user gateWay ...
m_userGateWay->m_interfaceClient.callForwardMultiple(
m_uid,
_value,
(uint64_t(m_uid) << 32) + uint64_t(transactionId));
// TODO : Check errors ...
}
}
void appl::ClientInterface::returnMessage(ememory::SharedPtr<zeus::Buffer> _data) {
APPL_ERROR("Get call from the Service to the user ...");
}

View File

@ -7,7 +7,7 @@
#include <zeus/WebServer.hpp>
#include <appl/GateWay.hpp>
#include <appl/ServiceInterface.hpp>
#include <appl/GateWayInterface.hpp>
namespace appl {
class GateWay;
@ -16,17 +16,16 @@ namespace appl {
enum class state {
unconnect, // starting sate
connect, // zeust get a TCP connection
userIdentify, // client set the user it want to access
clientIdentify, // client defien the mode of the acces (anonymous,client/user)
disconnect // client is dead or loal disconnection
};
enum state m_state; // state machine ...
private:
appl::GateWay* m_gatewayInterface;
zeus::WebServer m_interfaceClient;
bool requestURI(const std::string& _uri);
public:
ememory::SharedPtr<appl::ServiceInterface> m_userService;
std::vector<ememory::SharedPtr<appl::ServiceInterface>> m_listConnectedService;
ememory::SharedPtr<appl::GateWayInterface> m_userGateWay;
std::vector<ememory::SharedPtr<appl::GateWayInterface>> m_listConnectedService;
uint64_t m_uid;
uint64_t m_uid2;
std::string m_userConnectionName;

View File

@ -56,7 +56,7 @@ namespace appl {
enet::Tcp data = std::move(m_interface.waitNext());
ZEUS_VERBOSE("New connection");
if (m_service == true) {
m_gateway->newService(std::move(data));
m_gateway->newClientGateWayBackEnd(std::move(data));
} else {
m_gateway->newClient(std::move(data));
}
@ -65,11 +65,11 @@ namespace appl {
};
}
void appl::GateWay::newService(enet::Tcp _connection) {
void appl::GateWay::newClientGateWayBackEnd(enet::Tcp _connection) {
ZEUS_WARNING("New TCP connection (service)");
ememory::SharedPtr<appl::ServiceInterface> tmp = ememory::makeShared<appl::ServiceInterface>(std::move(_connection), this);
ememory::SharedPtr<appl::GateWayInterface> tmp = ememory::makeShared<appl::GateWayInterface>(std::move(_connection), this);
tmp->start();
m_serviceList.push_back(tmp);
m_gatewayBackEndList.push_back(tmp);
}
void appl::GateWay::newClient(enet::Tcp _connection) {
@ -84,11 +84,11 @@ appl::GateWay::GateWay() :
propertyClientIp(this, "client-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeClientIp),
propertyClientPort(this, "client-port", 1983, "Port to listen client", &appl::GateWay::onPropertyChangeClientPort),
propertyClientMax(this, "client-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeClientMax),
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", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeServiceMax) {
propertyGatewayBackEndIp(this, "gw-ip", "127.0.0.1", "Ip to listen client", &appl::GateWay::onPropertyChangeGateWayIp),
propertyGatewayBackEndPort(this, "gw-port", 1984, "Port to listen client", &appl::GateWay::onPropertyChangeGateWayPort),
propertyGatewayBackEndMax(this, "gw-max", 80, "Maximum of client at the same time", &appl::GateWay::onPropertyChangeGateWayMax) {
m_interfaceClientServer = ememory::makeShared<appl::TcpServerInput>(this, false);
m_interfaceServiceServer = ememory::makeShared<appl::TcpServerInput>(this, true);
m_interfaceGatewayBackEndServer = ememory::makeShared<appl::TcpServerInput>(this, true);
}
appl::GateWay::~GateWay() {
@ -97,19 +97,21 @@ appl::GateWay::~GateWay() {
void appl::GateWay::start() {
m_interfaceClientServer->start(*propertyClientIp, *propertyClientPort);
m_interfaceServiceServer->start(*propertyServiceIp, *propertyServicePort);
m_interfaceGatewayBackEndServer->start(*propertyGatewayBackEndIp, *propertyGatewayBackEndPort);
}
void appl::GateWay::stop() {
// TODO : Stop all server ...
}
ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string& _serviceName) {
for (auto &it : m_serviceList) {
ememory::SharedPtr<appl::GateWayInterface> appl::GateWay::get(const std::string& _userName) {
// TODO : Start USer only when needed, not get it all time started...
for (auto &it : m_gatewayBackEndList) {
if (it == nullptr) {
continue;
}
if (it->getName() != _serviceName) {
if (it->getName() != _userName) {
continue;
}
return it;
@ -117,14 +119,17 @@ ememory::SharedPtr<appl::ServiceInterface> appl::GateWay::get(const std::string&
return nullptr;
}
std::vector<std::string> appl::GateWay::getAllServiceName() {
std::vector<std::string> appl::GateWay::getAllUserName() {
std::vector<std::string> out;
for (auto &it : m_serviceList) {
/*
for (auto &it : m_gatewayBackEndList) {
if (it == nullptr) {
continue;
}
out.push_back(it->getName());
}
*/
return out;
}
@ -144,15 +149,15 @@ void appl::GateWay::answer(uint64_t _userSessionId, const ememory::SharedPtr<zeu
void appl::GateWay::cleanIO() {
auto it = m_serviceList.begin();
while (it != m_serviceList.end()) {
auto it = m_gatewayBackEndList.begin();
while (it != m_gatewayBackEndList.end()) {
if (*it != nullptr) {
if ((*it)->isAlive() == false) {
it = m_serviceList.erase(it);
it = m_gatewayBackEndList.erase(it);
continue;
}
} else {
it = m_serviceList.erase(it);
it = m_gatewayBackEndList.erase(it);
continue;
}
++it;
@ -193,14 +198,14 @@ void appl::GateWay::onPropertyChangeClientMax() {
}
void appl::GateWay::onPropertyChangeServiceIp() {
void appl::GateWay::onPropertyChangeGateWayIp() {
}
void appl::GateWay::onPropertyChangeServicePort() {
void appl::GateWay::onPropertyChangeGateWayPort() {
}
void appl::GateWay::onPropertyChangeServiceMax() {
void appl::GateWay::onPropertyChangeGateWayMax() {
}

View File

@ -0,0 +1,54 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <appl/GateWayInterface.hpp>
#include <appl/ClientInterface.hpp>
#include <eproperty/Value.hpp>
#include <ejson/Document.hpp>
namespace appl {
class TcpServerInput;
class GateWay : public eproperty::Interface {
private:
uint64_t m_clientUID;
private:
std::vector<ememory::SharedPtr<appl::GateWayInterface>> m_gatewayBackEndList; //!< List of all service availlable with their specific connection interface
std::vector<ememory::SharedPtr<appl::ClientInterface>> m_clientList; //!< List of all Client interface with their own connection
ememory::SharedPtr<appl::TcpServerInput> m_interfaceClientServer;
ememory::SharedPtr<appl::TcpServerInput> m_interfaceGatewayBackEndServer;
ejson::Document m_listUser;
public:
eproperty::Value<std::string> propertyClientIp;
eproperty::Value<uint16_t> propertyClientPort;
eproperty::Value<uint16_t> propertyClientMax;
eproperty::Value<std::string> propertyGatewayBackEndIp;
eproperty::Value<uint16_t> propertyGatewayBackEndPort;
eproperty::Value<uint16_t> propertyGatewayBackEndMax;
public:
GateWay();
virtual ~GateWay();
void start();
void stop();
// Get a specific user gateway:
ememory::SharedPtr<appl::GateWayInterface> get(const std::string& _userName);
std::vector<std::string> getAllUserName();
void answer(uint64_t _userSessionId, const ememory::SharedPtr<zeus::Buffer>& _data);
void newClientGateWayBackEnd(enet::Tcp _connection);
void newClient(enet::Tcp _connection);
void cleanIO();
private:
void onPropertyChangeClientIp();
void onPropertyChangeClientPort();
void onPropertyChangeClientMax();
void onPropertyChangeGateWayIp();
void onPropertyChangeGateWayPort();
void onPropertyChangeGateWayMax();
void onClientConnect(const bool& _value);
void onServiceConnect(const bool& _value);
};
}

View File

@ -0,0 +1,132 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/GateWayInterface.hpp>
#include <appl/ClientInterface.hpp>
#include <appl/GateWay.hpp>
// todo : cHANGE THIS ...
static const std::string protocolError = "PROTOCOL-ERROR";
appl::GateWayInterface::GateWayInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection), true) {
ZEUS_INFO("--------------------------");
ZEUS_INFO("-- NEW GateWay Back-end --");
ZEUS_INFO("--------------------------");
}
appl::GateWayInterface::~GateWayInterface() {
ZEUS_INFO("------------------------------");
ZEUS_INFO("-- DELETE GateWay Back-end --");
ZEUS_INFO("------------------------------");
}
bool appl::GateWayInterface::isAlive() {
return m_interfaceClient.isActive();
}
bool appl::GateWayInterface::requestURI(const std::string& _uri) {
ZEUS_INFO("request connect on User - GateWay: '" << _uri << "'");
if(m_gatewayInterface == nullptr) {
ZEUS_ERROR("Can not access to the main GateWay interface (nullptr)");
return false;
}
std::string tmpURI = _uri;
if (tmpURI.size() == 0) {
ZEUS_ERROR("Empty URI ... not supported ...");
return false;
}
if (tmpURI[0] == '/') {
tmpURI = std::string(tmpURI.begin() + 1, tmpURI.end());
}
// TODO : Remove subParameters xxx?YYY
// check if the USER is already connected:
ememory::SharedPtr<appl::GateWayInterface> tmp = m_gatewayInterface->get(tmpURI);
if (tmp != nullptr) {
ZEUS_ERROR("User is already connected ==> this is a big error ...");
return false;
}
m_name = tmpURI;
ZEUS_WARNING("Connection of user : '" << tmpURI << "'");
return true;
}
void appl::GateWayInterface::start() {
m_interfaceClient.connect(this, &appl::GateWayInterface::onServiceData);
m_interfaceClient.connectUri(this, &appl::GateWayInterface::requestURI);
m_interfaceClient.connect();
m_interfaceClient.setInterfaceName("srv-?");
}
void appl::GateWayInterface::stop() {
m_interfaceClient.disconnect();
}
void appl::GateWayInterface::SendData(uint64_t _userSessionId, ememory::SharedPtr<zeus::Buffer> _data) {
_data->setClientId(_userSessionId);
m_interfaceClient.writeBinary(_data);
}
void appl::GateWayInterface::onServiceData(ememory::SharedPtr<zeus::Buffer> _value) {
if (_value == nullptr) {
return;
}
uint32_t transactionId = _value->getTransactionId();
//data.add("from-service", ejson::String(m_name));
if (_value->getType() == zeus::Buffer::typeMessage::event) {
/*
if (data.valueExist("event") == true) {
// No need to have a user ID ...
if (data["event"].toString().get() == "IS-ALIVE") {
ZEUS_VERBOSE("Service Alive ...");
if (std::chrono::steady_clock::now() - m_interfaceClient.getLastTimeSend() >= std::chrono::seconds(20)) {
ejson::Object tmpp;
tmpp.add("event", ejson::String("IS-ALIVE"));
m_interfaceClient.writeJson(tmpp);
}
} else {
ZEUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
}
return;
}
*/
return;
}
if (_value->getType() == zeus::Buffer::typeMessage::call) {
ememory::SharedPtr<zeus::BufferCall> callObj = ememory::staticPointerCast<zeus::BufferCall>(_value);
std::string callFunction = callObj->getCall();
if (callFunction == "connect-service") {
if (m_name != "") {
ZEUS_WARNING("Service interface ==> try change the servie name after init: '" << callObj->getParameter<std::string>(0));
m_interfaceClient.answerValue(transactionId, false);
return;
}
m_name = callObj->getParameter<std::string>(0);
m_interfaceClient.setInterfaceName("srv-" + m_name);
m_interfaceClient.answerValue(transactionId, true);
return;
}
answerProtocolError(transactionId, "unknow function");
}
if (_value->getClientId() == 0) {
ZEUS_ERROR("Service interface ==> wrong service answer ==> missing 'client-id'");
return;
}
m_gatewayInterface->answer(_value->getClientId(), _value);
}
void appl::GateWayInterface::answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp) {
m_interfaceClient.answerError(_transactionId, protocolError, _errorHelp);
m_interfaceClient.disconnect(true);
}

View File

@ -0,0 +1,37 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <zeus/WebServer.hpp>
#include <ememory/memory.hpp>
namespace appl {
class GateWay;
class ClientInterface;
class GateWayInterface {
friend class appl::ClientInterface;
private:
appl::GateWay* m_gatewayInterface;
zeus::WebServer m_interfaceClient;
std::string m_name;
bool requestURI(const std::string& _uri);
public:
GateWayInterface(enet::Tcp _connection, appl::GateWay* _gatewayInterface);
virtual ~GateWayInterface();
void start();
void stop();
void onServiceData(ememory::SharedPtr<zeus::Buffer> _value);
public:
void SendData(uint64_t _userSessionId, ememory::SharedPtr<zeus::Buffer> _data);
const std::string& getName() {
return m_name;
}
bool isAlive();
protected:
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
};
}

View File

@ -0,0 +1,12 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
int32_t appl::getLogId() {
static int32_t g_val = elog::registerInstance("zeus-gateway");
return g_val;
}

View File

@ -0,0 +1,40 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <elog/log.hpp>
namespace appl {
int32_t getLogId();
};
#define APPL_BASE(info,data) ELOG_BASE(appl::getLogId(),info,data)
#define APPL_PRINT(data) APPL_BASE(-1, data)
#define APPL_CRITICAL(data) APPL_BASE(1, data)
#define APPL_ERROR(data) APPL_BASE(2, data)
#define APPL_WARNING(data) APPL_BASE(3, data)
#ifdef DEBUG
#define APPL_INFO(data) APPL_BASE(4, data)
#define APPL_DEBUG(data) APPL_BASE(5, data)
#define APPL_VERBOSE(data) APPL_BASE(6, data)
#define APPL_TODO(data) APPL_BASE(4, "TODO : " << data)
#else
#define APPL_INFO(data) do { } while(false)
#define APPL_DEBUG(data) do { } while(false)
#define APPL_VERBOSE(data) do { } while(false)
#define APPL_TODO(data) do { } while(false)
#endif
#define APPL_ASSERT(cond,data) \
do { \
if (!(cond)) { \
APPL_CRITICAL(data); \
assert(!#cond); \
} \
} while (0)

View File

@ -0,0 +1,59 @@
/** @file
* @author Edouard DUPIN
* @copyright 2014, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <appl/debug.hpp>
#include <appl/GateWay.hpp>
#include <etk/etk.hpp>
#include <zeus/zeus.hpp>
#include <etk/stdTools.hpp>
int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
zeus::init(_argc, _argv);
appl::GateWay basicGateway;
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if (etk::start_with(data, "--client-ip=") == true) {
basicGateway.propertyClientIp.set(std::string(&data[12]));
} else if (etk::start_with(data, "--client-port=") == true) {
basicGateway.propertyClientPort.set(etk::string_to_uint16_t(std::string(&data[14])));
} else if (etk::start_with(data, "--client-max=") == true) {
basicGateway.propertyClientMax.set(etk::string_to_uint16_t(std::string(&data[13])));
} else if (etk::start_with(data, "--gw-ip=") == true) {
basicGateway.propertyGatewayBackEndIp.set(std::string(&data[8]));
} else if (etk::start_with(data, "--gw-port=") == true) {
basicGateway.propertyGatewayBackEndPort.set(etk::string_to_uint16_t(std::string(&data[10])));
} else if (etk::start_with(data, "--gw-max=") == true) {
basicGateway.propertyGatewayBackEndMax.set(etk::string_to_uint16_t(std::string(&data[9])));
} else if ( data == "-h"
|| data == "--help") {
APPL_PRINT(etk::getApplicationName() << " - help : ");
APPL_PRINT(" " << _argv[0] << " [options]");
APPL_PRINT(" --client-ip=XXX Client connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --client-port=XXX Client connection PORT (default: 1983)");
APPL_PRINT(" --client-max=XXX Client Maximum parallele connection (default: 80)");
APPL_PRINT(" --gw-ip=XXX Back-end Gateway connection IP (default: 1.7.0.0.1)");
APPL_PRINT(" --gw-port=XXX Back-end Gateway connection PORT (default: 1984)");
APPL_PRINT(" --gw-max=XXX Back-end Gateway Maximum IO (default: 15)");
return -1;
}
}
APPL_INFO("==================================");
APPL_INFO("== ZEUS gateway start ==");
APPL_INFO("==================================");
basicGateway.start();
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
basicGateway.cleanIO();
}
basicGateway.stop();
APPL_INFO("==================================");
APPL_INFO("== ZEUS gateway stop ==");
APPL_INFO("==================================");
return 0;
}

View File

@ -0,0 +1,40 @@
#!/usr/bin/python
import lutin.debug as debug
import lutin.tools as tools
def get_type():
return "BINARY"
def get_sub_type():
return "TOOLS"
def get_desc():
return "ZEUS generic gateway"
def get_licence():
return "APACHE-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def configure(target, my_module):
my_module.add_path(".")
my_module.add_depend(['zeus', 'ejson'])
my_module.add_src_file([
'appl/debug.cpp',
'appl/ClientInterface.cpp',
'appl/GateWayInterface.cpp',
'appl/GateWay.cpp',
'appl/main.cpp'
])
return True

View File

@ -296,7 +296,7 @@ int appl::MediaDecoder::open_codec_context(int *_streamId, AVFormatContext *_for
}
// Init the decoders, with or without reference counting
av_dict_set(&opts, "refcounted_frames", "0", 0);
//av_dict_set(&opts, "threads", "auto", 0);
av_dict_set(&opts, "threads", "auto", 0);
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
APPL_ERROR("Failed to open " << av_get_media_type_string(_type) << " codec");
return ret;

View File

@ -49,10 +49,11 @@ bool zeus::Client::connectTo(const std::string& _address) {
ZEUS_ERROR("Allocate connection error");
return false;
}
ZEUS_WARNING("Request connect user " << _address);
m_interfaceClient->connect(this, &zeus::Client::onClientData);
m_interfaceClient->setInterface(std::move(connection), false);
m_interfaceClient->setInterface(std::move(connection), false, _address);
m_interfaceClient->connect();
/*
ZEUS_WARNING("Request connect user " << _address);
zeus::Future<bool> ret = call("connectToUser", _address, "zeus-client");
ret.wait();
@ -68,6 +69,9 @@ bool zeus::Client::connectTo(const std::string& _address) {
ZEUS_WARNING(" ==> Refuse connection");
}
return ret.get();
*/
// TODO: Check if connection is retruen OK or arror ...
return true;
}
bool zeus::Client::connect(const std::string& _address) {

View File

@ -44,7 +44,7 @@ zeus::WebServer::WebServer(enet::Tcp _connection, bool _isServer) :
setInterface(std::move(_connection), _isServer);
}
void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer) {
void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName) {
m_connection.setInterface(std::move(_connection), _isServer);
m_connection.connect(this, &zeus::WebServer::onReceiveData);
if (_isServer == true) {
@ -54,7 +54,7 @@ void zeus::WebServer::setInterface(enet::Tcp _connection, bool _isServer) {
std::vector<std::string> protocols;
protocols.push_back("zeus/0.8");
protocols.push_back("zeus/1.0");
m_connection.start("/stupidName", protocols);
m_connection.start("/" + _userName, protocols);
}
}
@ -177,8 +177,9 @@ bool zeus::WebServer::onReceiveUri(const std::string& _uri, const std::vector<st
break;
}
}
if (_uri == "/stupidName") {
return true;
// TODO : Add better return on specific user ...
if (m_observerRequestUri != nullptr) {
return m_observerRequestUri(_uri);
}
return false;
}
@ -355,7 +356,7 @@ void zeus::WebServer::callForwardMultiple(uint32_t _clientId,
for (auto &itCall : m_pendingCall) {
ZEUS_INFO(" compare : " << itCall.first << " =?= " << _singleReferenceId);
if (itCall.first == _singleReferenceId) {
// Find element ==> transit it ...
// Find element ==> transmit it ...
_buffer->setTransactionId(itCall.second.getTransactionId());
_buffer->setClientId(_clientId);
writeBinary(_buffer);

View File

@ -110,6 +110,26 @@ namespace zeus {
(*_class.*_func)(_value);
};
}
public:
using ObserverRequestUri = std::function<bool(const std::string&)>; //!< Define an Observer on the specific URI requested callback: function pointer (return true if the connection is accepted or not)
protected:
ObserverRequestUri m_observerRequestUri;
public:
/**
* @brief Connect on the URI requested.
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
* @param[in] _func Function to call.
*/
template<class CLASS_TYPE>
void connectUri(CLASS_TYPE* _class, bool (CLASS_TYPE::*_func)(const std::string&)) {
m_observerRequestUri = [=](const std::string& _value){
return (*_class.*_func)(_value);
};
}
void connectUri(WebServer::ObserverRequestUri _func) {
m_observerRequestUri = _func;
}
public:
/**
* @brief
@ -134,7 +154,7 @@ namespace zeus {
* @param[in]
* @return
*/
void setInterface(enet::Tcp _connection, bool _isServer);
void setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName="");
/**
* @brief
* @param[in]