JD2022-TU1/main/extern/dtest/dtcore/inc/dtservice.h

259 lines
8.6 KiB
C++

#pragma once
#include "dtcore/inc/dtdefinitions.h"
#include "dtcore/inc/dtconnectiondescriptor.h"
#include "dtcore/inc/dtmessage.h"
#include "dtcore/inc/dtfunctor.h"
#include "dtcore/inc/dtmutex.h"
namespace dt
{
class ByteBuffer;
class ClientService;
class ServerService;
class Service;
class WebResponse;
class Task;
template <class T> class Promise;
class PromiseBase;
// Common Headers
const char* const g_HttpHeaderUserAgent = "User-Agent";
const char* const g_HttpHeaderUserAgentVersion = "User-Agent-Version";
const char* const g_HttpHeaderUserAgentPid = "User-Agent-Pid";
const char* const g_HttpHeaderUserAgentComputer = "User-Agent-Computer";
const char* const g_HttpHeaderUser = "User";
const char* const g_HttpHeaderSessionRenew = "Session-Renew";
// Common Cookies
const char* const g_HttpCookieSession = "Session";
enum class HttpCode : int
{
None = 0,
Continue = 100,
SwitchingProtocols = 101,
Processing = 102,
Ok = 200,
Created = 201,
Accepted = 202,
NonAuthoritativeInformation = 203,
NoContent = 204,
ResetContent = 205,
PartialContent = 206,
MultiStatus = 207,
MultipleChoices = 300,
MovedPermanently = 301,
Found = 302,
SeeOther = 303,
NotModified = 304,
UseProxy = 305,
SwitchProxy = 306,
TemporaryRedirect = 307,
BadRequest = 400,
Unauthorized = 401,
PaymentRequired = 402,
Forbidden = 403,
NotFound = 404,
MethodNotAllowed = 405,
NotAcceptable = 406,
ProxyAuthenticationRequired = 407,
RequestTimeout = 408,
Conflict = 409,
Gone = 410,
LengthRequired = 411,
PreconditionFailed = 412,
RequestEntityTooLarge = 413,
RequestUriTooLong = 414,
UnsupportedMediaType = 415,
RequestedRangeNotSatisfiable = 416,
ExpectationFailed = 417,
UnprocessableEntity = 422,
Locked = 423,
FailedDependency = 424,
UnorderedCollection = 425,
UpgradeRequired = 426,
NoResponse = 444,
RetryWith = 449,
BlockedByWindowsParentalControls = 450,
UnavailableForLegalReasons = 451,
InternalServerError = 500,
NotImplemented = 501,
BadGateway = 502,
ServiceUnavailable = 503,
GatewayTimeout = 504,
HttpVersionNotSupported = 505,
VariantAlsoNegotiates = 506,
InsufficientStorage = 507,
BandwidthLimitExceeded = 509,
NotExtended = 510,
// local send/receive errors
InternalError = 1000,
InternalSocketError = 1001,
InternalHostInvalid = 1002,
InternalTimeout = 1003,
InternalDisconnect = 1004,
InternalCancel = 1005
};
String HttpCodeToString(HttpCode code);
//////////////////////////////////////////////////////////////////////////
class MessageEmpty : public Message
{
DT_DECLARE_TYPE(MessageEmpty, Message);
public:
MessageEmpty(){}
static Message* Create() { return DT_NEW(MessageEmpty); }
virtual void Serialize(U8 , Stream& ) override {};
private:
};
//////////////////////////////////////////////////////////////////////////
class Service
{
DT_DECLARE_ROOT_TYPE(Service)
public:
virtual ~Service() {};
virtual const char* GetHttpId() const = 0;
virtual void Update() {}
MessageFactory& GetMessageFactory() { return m_MessageFactory; }
protected:
MessageFactory m_MessageFactory;
};
//////////////////////////////////////////////////////////////////////////
class ClientSessionInterface
{
public:
virtual ~ClientSessionInterface() {};
virtual Promise<WebResponse> PostAsync(ClientService& service, const Message& msg, MilliSeconds timeoutMs) = 0;
virtual void Join(const PromiseBase& promise) = 0;
virtual void RequestShutdown() = 0;
virtual void Connect(const ConnectionDescriptor& connection,
const String& userName,
const String& computerName,
const String& moduleName,
int processId,
ByteBuffer& attachment) = 0;
virtual void DisconnectQuery(const ConnectionDescriptor& connection, bool& canDisconnect) = 0;
virtual void DisconnectAll() = 0;
virtual void Disconnect(const ConnectionDescriptor& connection) = 0;
};
//////////////////////////////////////////////////////////////////////////
class ClientService : public Service
{
DT_DECLARE_TYPE(ClientService, Service)
public:
// override as needed
virtual void OnConnect(bool renew) { DT_UNUSED(renew); }
virtual void OnDisconnect(bool remoteDisconnect) { DT_UNUSED(remoteDisconnect); }
virtual void OnDisconnectQuery(bool& canDisconnect) { canDisconnect = true; }
// service method
void Disconnect();
Promise<WebResponse> PostAsync(const Message& msg, MilliSeconds timeoutMs = MilliSeconds(INVALID_VALUE));
void Join(const PromiseBase& promise);
void RequestShutdown();
const ConnectionDescriptor& GetConnectionDescriptor() const { return m_ConnectionDescriptor; }
const ConnectionDescriptor& GetLocalConnectionDescriptor() const { return m_LocalConnectionDescriptor; }
public: // internal API
void InternalBind(ClientSessionInterface* session,
const ConnectionDescriptor& descriptor,
const ConnectionDescriptor& localDescriptor);
void InternalUnbind();
void InternalOnConnect(const ConnectionDescriptor& descriptor,
const ConnectionDescriptor& localDescriptor,
bool renew);
void InternalOnMessage(const String& route, Message* msg);
private:
ConnectionDescriptor m_ConnectionDescriptor;
ConnectionDescriptor m_LocalConnectionDescriptor;
ClientSessionInterface* m_Session = nullptr;
};
//////////////////////////////////////////////////////////////////////////
class ServerSessionInterface
{
public:
virtual ~ServerSessionInterface() {}
virtual void Reply(const ConnectionDescriptor& descriptor,
const Message& msg,
HttpCode code) = 0;
virtual void Download(const ConnectionDescriptor& descriptor,
const String& filename,
const ByteBuffer& data,
HttpCode code) = 0;
virtual void Notify(const ConnectionDescriptor& descriptor,
const Service& service,
const Message& msg) = 0;
virtual void OnLoggedIn(const ConnectionDescriptor& descriptor,
const String& userName,
const Strings& roles) = 0;
virtual void OnLoggedOut(const ConnectionDescriptor& descriptor) = 0;
virtual int GetNumberOfConnections() const = 0;
};
//////////////////////////////////////////////////////////////////////////
class ServerService : public Service
{
DT_DECLARE_TYPE(ServerService, Service)
public:
// override as needed
virtual void OnBind() {}
virtual void OnConnect(const ConnectionDescriptor& descriptor, bool renew) { DT_UNUSED(descriptor); DT_UNUSED(renew); }
virtual void OnDisconnect(const ConnectionDescriptor&, bool remoteDisconnect) { DT_UNUSED(remoteDisconnect); }
virtual void OnDisconnectQuery(const ConnectionDescriptor&, bool& canDisconnect) { canDisconnect = true; }
// service methods
void Reply(const ConnectionDescriptor& descriptor, const Message& msg = MessageEmpty(), HttpCode code = HttpCode::Ok);
void Download(const ConnectionDescriptor& descriptor,
const String& filename,
const ByteBuffer& data,
HttpCode code = HttpCode::Ok);
void Notify(const ConnectionDescriptor& descriptor, const Message& msg);
int GetNumberOfConnections() const;
const ConnectionDescriptor& GetLocalHttpConnectionDescriptor() const { return m_LocalHttpConnectionDescriptor; }
public: // internal API
void InternalOnMessage(const ConnectionDescriptor& descriptor,
const String& route,
Message* msg);
void InternalBind(ServerSessionInterface* session,
const ConnectionDescriptor& localDescriptor);
ServerSessionInterface* InternalGetHttpSession() const { return m_HttpSession; }
private:
ConnectionDescriptor m_LocalHttpConnectionDescriptor;
ServerSessionInterface* m_HttpSession = nullptr;
};
}