198 lines
7.7 KiB
C++
198 lines
7.7 KiB
C++
/** @file
|
|
* @author Edouard DUPIN
|
|
* @copyright 2016, Edouard DUPIN, all right reserved
|
|
* @license MPL v2.0 (see license file)
|
|
*/
|
|
#pragma once
|
|
|
|
#include <zeus/WebServer.hpp>
|
|
#include <eproperty/Value.hpp>
|
|
#include <zeus/debug.hpp>
|
|
#include <chrono>
|
|
|
|
#include <zeus/Future.hpp>
|
|
#include <zeus/ObjectRemote.hpp>
|
|
#include <zeus/Object.hpp>
|
|
|
|
namespace zeus {
|
|
class Object;
|
|
/**
|
|
* @brief Client interface to acces on the remote service and gateway
|
|
*/
|
|
class Client : public eproperty::Interface {
|
|
friend class ObjectRemote;
|
|
public:
|
|
eproperty::Value<etk::String> propertyIp; //!< Ip of WebSocket TCP connection
|
|
eproperty::Value<uint16_t> propertyPort; //!< Port of the WebSocket connection
|
|
public:
|
|
etk::String m_clientName; //!< Local client name to generate the local serrvice name if needed (if direct connection ==> no name)
|
|
ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< Interface on the Websocket interface
|
|
etk::Vector<ememory::WeakPtr<zeus::ObjectRemoteBase>> m_listConnectedService; //!< Connect only one time on each service, not needed more.
|
|
public:
|
|
/**
|
|
* @brief answer a protocol error on the websocket ==> this stop the communication
|
|
* @param[in] _transactionId The tansation ID that have an error
|
|
* @param[in] _errorHelp Help developper/user to understand where the problem come from.
|
|
*/
|
|
void answerProtocolError(uint32_t _transactionId, const etk::String& _errorHelp);
|
|
/**
|
|
* @brief Get the client web interface
|
|
* @return A shared pointer on the client server
|
|
*/
|
|
ememory::SharedPtr<zeus::WebServer> getWebInterface() {
|
|
return m_interfaceWeb;
|
|
}
|
|
/**
|
|
* @brief Contructor of a client
|
|
*/
|
|
Client();
|
|
/**
|
|
* @brief Destructor of a client
|
|
*/
|
|
virtual ~Client();
|
|
protected:
|
|
/**
|
|
* @brief Connect to a remote extern server
|
|
* @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993"
|
|
* @param[in] _timeOut duration that we are waiting the server answer
|
|
*/
|
|
bool connectTo(const etk::String& _address, echrono::Duration _timeOut = echrono::seconds(1));
|
|
public:
|
|
/**
|
|
* @brief Direct connection on a GateWay No Identification needed, the Port on the Gateway garenty the connection)
|
|
* @note This is exclusively reserve for server service provicers
|
|
* @param[in] _timeOut duration that we are waiting the server answer
|
|
*/
|
|
bool connect(echrono::Duration _timeOut = echrono::seconds(1));
|
|
/**
|
|
* @brief Create a client on a specific user in an ANONIMOUS way
|
|
* @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993"
|
|
* @param[in] _timeOut duration that we are waiting the server answer
|
|
*/
|
|
bool connect(const etk::String& _address, echrono::Duration _timeOut = echrono::seconds(1));
|
|
/**
|
|
* @brief Create a client on a specific user in a user mode (connect to your personnal account)
|
|
* @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993"
|
|
* @param[in] _userPassword Password of the user
|
|
* @param[in] _timeOut duration that we are waiting the server answer
|
|
*/
|
|
bool connect(const etk::String& _address, const etk::String& _userPassword, echrono::Duration _timeOut = echrono::seconds(1));
|
|
/**
|
|
* @brief Create a client on a specific user in a client mode with the tocken associated
|
|
* @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993"
|
|
* @param[in]
|
|
* @param[in]
|
|
* @param[in] _timeOut duration that we are waiting the server answer
|
|
*/
|
|
bool connect(const etk::String& _address, const etk::String& _clientName, const etk::String& _clientTocken, echrono::Duration _timeOut = echrono::seconds(1));
|
|
/**
|
|
* @brief Disconnect of the current interface
|
|
*/
|
|
void disconnect();
|
|
public:
|
|
/**
|
|
* @brief Get a remote service
|
|
* @param[in] _serviceName Name of the service
|
|
* @return Pointer on an interface of remote service
|
|
*/
|
|
zeus::ObjectRemote getService(const etk::String& _serviceName);
|
|
|
|
using factoryService = etk::Function<void(uint32_t, ememory::SharedPtr<zeus::WebServer>& _iface, uint32_t _destination)>; //!< call this function anser to the caller the requested Object
|
|
|
|
etk::Map<etk::String,factoryService> m_listServicesAvaillable; //!< list of all factory availlable (to create new services)
|
|
/**
|
|
* @brief Provide a service with a specific name
|
|
* @param[in] _serviceName Name of the service
|
|
* @param[in] _service handle on the service provided
|
|
* @return true if the service is acepted or false if not
|
|
*/
|
|
bool serviceAdd(const etk::String& _serviceName, factoryService _factory);
|
|
/**
|
|
* @brief Revmove a service from the list of availlable services
|
|
* @param[in] _serviceName Name of the service to remove
|
|
* @return true The service has been removed, false otherwise.
|
|
*/
|
|
bool serviceRemove(const etk::String& _serviceName);
|
|
private:
|
|
/**
|
|
* @brief When receive data from the websocket ... call this ...
|
|
* @param[in] _value New input buffer
|
|
*/
|
|
void onClientData(ememory::SharedPtr<zeus::Message> _value);
|
|
public:
|
|
/**
|
|
* @brief Create a call on the interface gateway (threw the router)
|
|
* @param[in] _functionName name of the function to call
|
|
* @param[in] _args... multiple argument neededs
|
|
* @return a future that will contain the aswer when receiveed (need to transmit over ethernet)
|
|
*/
|
|
template<class... _ARGS>
|
|
zeus::FutureBase call(uint16_t _srcObjectId,
|
|
uint32_t _destination,
|
|
const etk::String& _functionName,
|
|
_ARGS&&... _args) {
|
|
if (m_interfaceWeb == null) {
|
|
ememory::SharedPtr<zeus::message::Answer> ret = zeus::message::Answer::create(null); // TODO : This is really a bad case ...
|
|
ret->addError("NULLPTR", "call " + _functionName + " with no interface open");
|
|
return zeus::FutureBase(0, ret);
|
|
}
|
|
uint32_t source = (uint32_t(m_interfaceWeb->getAddress()) << 16) + _srcObjectId;
|
|
return m_interfaceWeb->call(source, _destination, _functionName, _args...);
|
|
}
|
|
uint16_t getlocalAddress() {
|
|
return m_interfaceWeb->getAddress();
|
|
}
|
|
private:
|
|
/**
|
|
* @brief Internal (called when user change the Ip of the client interface)
|
|
*/
|
|
void onPropertyChangeIp();
|
|
/**
|
|
* @brief Internal (called when user change the port of the client interface)
|
|
*/
|
|
void onPropertyChangePort();
|
|
public:
|
|
/**
|
|
* @brief Send a ping to prevent the protocol time-out (no transmission)
|
|
* @note let the system use this function.
|
|
*/
|
|
void pingIsAlive();
|
|
/**
|
|
* @brief Check if the server/connection is alive
|
|
* @return true The connection is alive
|
|
* @return false The connection is dead
|
|
*/
|
|
bool isAlive();
|
|
/**
|
|
* @brief Display all connected object remote and local ...
|
|
*/
|
|
void displayConnectedObject();
|
|
/**
|
|
* @brief Display all connected object remote and local ...
|
|
*/
|
|
void cleanDeadObject();
|
|
public:
|
|
// TODO: Remove this from here ... ==> create a proxy to gateway (service manager)
|
|
/**
|
|
* @brief Get the number of services.
|
|
* @return Future on the services count.
|
|
*/
|
|
zeus::Future<int32_t> getServiceCount();
|
|
/**
|
|
* @brief Get the whole list of services availlable
|
|
* @return Future on the list of service (names)
|
|
*/
|
|
zeus::Future<etk::Vector<etk::String>> getServiceList();
|
|
// TODO : This is an active waiting ==> this is bad ... ==> use future, it will be better
|
|
/**
|
|
* @brief Wait for a service wake up (and be availlable)
|
|
* @param[in] _serviceName Name of the service to wait.
|
|
* @param[in] _delta Duration to wait the service
|
|
* @return true The service is availlable
|
|
* @return false The service is not availlable.
|
|
*/
|
|
bool waitForService(const etk::String& _serviceName, echrono::Duration _delta = echrono::seconds(1));
|
|
};
|
|
}
|
|
|