mirror of
https://github.com/vczh-libraries/Release.git
synced 2026-08-18 01:44:28 +08:00
689 lines
22 KiB
C++
689 lines
22 KiB
C++
/***********************************************************************
|
|
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
|
|
DEVELOPER: Zihan Chen(vczh)
|
|
***********************************************************************/
|
|
#include "VlppOS.h"
|
|
#include "Vlpp.h"
|
|
|
|
/***********************************************************************
|
|
.\NETWORKPROTOCOL.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_NETWORKPROTOCOL
|
|
#define VCZH_INTERPROCESS_WINDOWS_NETWORKPROTOCOL
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#define _WINSOCKAPI_
|
|
#include <windows.h>
|
|
#include <http.h>
|
|
#define RPC_USE_NATIVE_WCHAR
|
|
#include <rpc.h>
|
|
#include <winhttp.h>
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
/*
|
|
* GET: /Request
|
|
* To connect and initialize the server.
|
|
* Returns available URLs.
|
|
*
|
|
* It can only be called once, all subsequence calls will be rejected.
|
|
*/
|
|
constexpr const wchar_t* HttpServerUrl_Connect = L"/VlppInterProcess/Connect";
|
|
|
|
/*
|
|
* POST: /Request/GUID
|
|
* Client should always maintain a living request on the server.
|
|
*
|
|
* Returns only when a request is issued.
|
|
* It will be pending or timeout if no request is issued.
|
|
* If a request is issued but no living request available, it waits.
|
|
*/
|
|
constexpr const wchar_t* HttpServerUrl_Request = L"/VlppInterProcess/Request";
|
|
|
|
/*
|
|
* POST: /Response/GUID
|
|
* To send responses or events to the server.
|
|
* Returns nothing.
|
|
*/
|
|
constexpr const wchar_t* HttpServerUrl_Response = L"/VlppInterProcess/Response";
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\HTTPCLIENTAPI.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
HttpClientApi
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_HTTPCLIENTAPI
|
|
#define VCZH_INTERPROCESS_WINDOWS_HTTPCLIENTAPI
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
|
|
/// <summary>An http request.</summary>
|
|
class HttpRequest
|
|
{
|
|
typedef collections::Array<char> BodyBuffer;
|
|
typedef collections::List<WString> StringList;
|
|
typedef collections::Dictionary<WString, WString> HeaderMap;
|
|
public:
|
|
/// <summary>Query of the request, like "/index.html".</summary>
|
|
WString query;
|
|
/// <summary>Set to true if the request uses SSL, or https.</summary>
|
|
bool secure = false;
|
|
/// <summary>User name to authorize. Set to empty if authorization is not needed.</summary>
|
|
WString username;
|
|
/// <summary>Password to authorize. Set to empty if authorization is not needed.</summary>
|
|
WString password;
|
|
/// <summary>HTTP method, like "GET", "POST", "PUT", "DELETE", etc.</summary>
|
|
WString method;
|
|
/// <summary>Cookie. Set to empty if cookie is not needed.</summary>
|
|
WString cookie;
|
|
/// <summary>Request body. This is a byte array.</summary>
|
|
BodyBuffer body;
|
|
/// <summary>Content type, like "text/xml".</summary>
|
|
WString contentType;
|
|
/// <summary>Accept type list, elements like "text/xml".</summary>
|
|
StringList acceptTypes;
|
|
/// <summary>A dictionary to contain extra headers.</summary>
|
|
HeaderMap extraHeaders;
|
|
/// <summary>Set to true to let this request finish when <see cref="HttpClientApi.Stop"/> is called.</summary>
|
|
bool keepAliveOnStop = false;
|
|
/// <summary>Timeout for resolving the host name. 0 or -1 means infinite.</summary>
|
|
vint resolveTimeout = 0;
|
|
/// <summary>Timeout for connecting to the server. 0 or -1 means infinite.</summary>
|
|
vint connectTimeout = 60000;
|
|
/// <summary>Timeout for sending the request. 0 or -1 means infinite.</summary>
|
|
vint sendTimeout = 30000;
|
|
/// <summary>Timeout for receiving the response. 0 or -1 means infinite.</summary>
|
|
vint receiveTimeout = 30000;
|
|
|
|
HttpRequest() = default;
|
|
void SetBodyUtf8(const WString& bodyString);
|
|
};
|
|
|
|
/// <summary>A type representing an http response.</summary>
|
|
class HttpResponse
|
|
{
|
|
typedef collections::Array<char> BodyBuffer;
|
|
public:
|
|
/// <summary>Status code, like 200.</summary>
|
|
vint statusCode = 0;
|
|
/// <summary>Response body. This is a byte array.</summary>
|
|
BodyBuffer body;
|
|
/// <summary>Returned cookie from the server.</summary>
|
|
WString cookie;
|
|
/// <summary>Returned content type from the server.</summary>
|
|
WString contentType;
|
|
|
|
HttpResponse() = default;
|
|
WString GetBodyUtf8() const;
|
|
};
|
|
|
|
/// <summary>A transport error reported by the underlying Windows HTTP API.</summary>
|
|
class HttpError
|
|
{
|
|
public:
|
|
DWORD errorCode = 0;
|
|
WString operation;
|
|
WString message;
|
|
};
|
|
|
|
/// <summary>A Windows-only async HTTP client for a single host and port.</summary>
|
|
class HttpClientApi : public Object
|
|
{
|
|
static constexpr vint32_t HttpRespondBodyStep = 65536;
|
|
|
|
class HttpRequestContext : public Object
|
|
{
|
|
public:
|
|
HttpClientApi* api = nullptr;
|
|
HINTERNET httpRequest = NULL;
|
|
Func<void(Variant<HttpResponse, HttpError>)> callback;
|
|
collections::Array<char> requestBody;
|
|
HttpResponse response;
|
|
DWORD bodyBufferWriting = 0;
|
|
DWORD bodyBufferWritingAvailable = 0;
|
|
bool keepAliveOnStop = false;
|
|
bool completed = false;
|
|
bool closing = false;
|
|
SpinLock lockContext;
|
|
};
|
|
|
|
WString server;
|
|
vint port = 0;
|
|
HINTERNET httpSession = NULL;
|
|
HINTERNET httpConnection = NULL;
|
|
|
|
SpinLock lockActiveRequests;
|
|
collections::List<Ptr<HttpRequestContext>> activeRequests;
|
|
bool stopping = false;
|
|
atomic_vint pendingCallbacks = 0;
|
|
EventObject eventPendingCallbacks;
|
|
|
|
static void CALLBACK HttpStatusCallback(HINTERNET httpRequest, DWORD_PTR context, DWORD status, LPVOID statusInformation, DWORD statusInformationLength);
|
|
static HttpError MakeError(const WString& operation, DWORD errorCode);
|
|
static vint HexValue(wchar_t c);
|
|
|
|
bool IsStopping();
|
|
void BeginPendingCallback();
|
|
void EndPendingCallback();
|
|
void AttachRequestUnsafe(Ptr<HttpRequestContext> context);
|
|
void RemoveRequestUnsafe(Ptr<HttpRequestContext> context);
|
|
void CloseRequest(Ptr<HttpRequestContext> context);
|
|
void OnRequestHandleClosing(Ptr<HttpRequestContext> context);
|
|
void CompleteRequest(Ptr<HttpRequestContext> context, HttpResponse&& response);
|
|
void CompleteRequest(Ptr<HttpRequestContext> context, HttpError&& error);
|
|
void CompleteRequestWithLastError(Ptr<HttpRequestContext> context, const WString& operation, DWORD errorCode);
|
|
|
|
public:
|
|
HttpClientApi(const WString& _server, vint _port);
|
|
~HttpClientApi();
|
|
|
|
HttpClientApi(const HttpClientApi&) = delete;
|
|
HttpClientApi(HttpClientApi&&) = delete;
|
|
HttpClientApi& operator=(const HttpClientApi&) = delete;
|
|
HttpClientApi& operator=(HttpClientApi&&) = delete;
|
|
|
|
void HttpQuery(const HttpRequest& request, Func<void(Variant<HttpResponse, HttpError>)> callback);
|
|
void Stop();
|
|
|
|
static WString UrlEncodeQuery(const WString& query);
|
|
static WString UrlDecodeQuery(const WString& query);
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\HTTPCLIENT.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
HttpClient
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_HTTPCLIENT
|
|
#define VCZH_INTERPROCESS_WINDOWS_HTTPCLIENT
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
|
|
class HttpClient : public Object, public virtual INetworkProtocolConnection, public virtual INetworkProtocolClient
|
|
{
|
|
protected:
|
|
static constexpr vint HttpRequestMaxAttempts = 3;
|
|
|
|
enum class State
|
|
{
|
|
Ready,
|
|
WaitForServerConnection,
|
|
Running,
|
|
Stopping,
|
|
};
|
|
|
|
State state = State::Ready;
|
|
INetworkProtocolCallback* callback = nullptr;
|
|
WString baseUrl;
|
|
Ptr<HttpClientApi> httpClientApi;
|
|
WString urlConnect;
|
|
WString urlRequest;
|
|
WString urlResponse;
|
|
SpinLock lockState;
|
|
|
|
/***********************************************************************
|
|
HttpClient (Reading)
|
|
***********************************************************************/
|
|
|
|
protected:
|
|
static constexpr const wchar_t* JsonContentType = L"application/json; charset=utf8";
|
|
|
|
void RaiseLocalError(WString errorMessage, bool fatal);
|
|
bool IsStopping();
|
|
public:
|
|
|
|
void BeginReadingLoopUnsafe() override;
|
|
|
|
/***********************************************************************
|
|
HttpClient (WaitForServer)
|
|
***********************************************************************/
|
|
|
|
protected:
|
|
|
|
EventObject eventWaitForServer;
|
|
SpinLock lockConnectResult;
|
|
bool connectCompleted = false;
|
|
WString connectResponse;
|
|
WString connectError;
|
|
void CompleteConnectRequest(const WString& response, const WString& error);
|
|
|
|
public:
|
|
|
|
INetworkProtocolConnection* GetConnection() override;
|
|
void WaitForServer() override;
|
|
ClientStatus GetStatus() override;
|
|
|
|
/***********************************************************************
|
|
HttpClient (Writing)
|
|
***********************************************************************/
|
|
|
|
protected:
|
|
enum class HttpRequestType
|
|
{
|
|
Connect,
|
|
Request,
|
|
Response,
|
|
};
|
|
|
|
bool SendHttpRequest(HttpRequestType requestType, const wchar_t* method, const WString& url, const WString& body, vint attempt = 1);
|
|
void OnHttpRequestCompleted(HttpRequestType requestType, WString body, vint attempt, Variant<HttpResponse, HttpError> result);
|
|
void OnHttpRequestFailed(HttpRequestType requestType, const WString& body, vint attempt, const WString& errorMessage);
|
|
|
|
public:
|
|
|
|
void SendString(const WString& str) override;
|
|
|
|
/***********************************************************************
|
|
HttpClient
|
|
***********************************************************************/
|
|
|
|
public:
|
|
HttpClient(const WString _baseUrl, vint port);
|
|
~HttpClient();
|
|
|
|
void InstallCallback(INetworkProtocolCallback* _callback) override;
|
|
void Stop() override;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\HTTPSERVERAPI.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
HttpServerApi
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_HTTPSERVERAPI
|
|
#define VCZH_INTERPROCESS_WINDOWS_HTTPSERVERAPI
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
|
|
/// <summary>A response to be sent by <see cref="HttpServerApi"/>.</summary>
|
|
struct HttpServerResponse
|
|
{
|
|
vint statusCode = 200;
|
|
WString reason;
|
|
WString body;
|
|
WString contentType;
|
|
};
|
|
|
|
/// <summary>A Windows-only async HTTP server for a single URL prefix.</summary>
|
|
class HttpServerApi : public Object
|
|
{
|
|
static constexpr vint32_t HttpRequestBufferInitSize = 1024;
|
|
|
|
protected:
|
|
enum class State
|
|
{
|
|
Ready,
|
|
Running,
|
|
Stopping,
|
|
};
|
|
|
|
WString urlPrefix;
|
|
bool respondToOptions = false;
|
|
|
|
HANDLE httpRequestQueue = INVALID_HANDLE_VALUE;
|
|
HTTP_SERVER_SESSION_ID httpSessionId = HTTP_NULL_ID;
|
|
HTTP_URL_GROUP_ID httpUrlGroupId = HTTP_NULL_ID;
|
|
|
|
State state = State::Ready;
|
|
|
|
collections::Array<BYTE> bufferRequest;
|
|
HANDLE hWaitHandleRequest = INVALID_HANDLE_VALUE;
|
|
OVERLAPPED overlappedRequest;
|
|
HANDLE hEventRequest = INVALID_HANDLE_VALUE;
|
|
EventObject eventPendingCallbacks;
|
|
atomic_vint pendingCallbacks = 0;
|
|
|
|
void OnHttpConnectionBrokenUnsafe();
|
|
void OnHttpRequestReceivedUnsafe(PHTTP_REQUEST pRequest);
|
|
ULONG ListenToHttpRequest_Init(OVERLAPPED* overlapped);
|
|
ULONG ListenToHttpRequest_InitMoreData(ULONG* bytesReturned);
|
|
ULONG ListenToHttpRequest_OverlappedMoreData(vint expectedBufferSize);
|
|
void ListenToHttpRequest();
|
|
void BeginPendingCallback();
|
|
void EndPendingCallback();
|
|
|
|
virtual void OnHttpRequestReceived(PHTTP_REQUEST pRequest) = 0;
|
|
virtual void OnHttpServerStopping();
|
|
|
|
static void SendOptionsResponse(HANDLE httpRequestQueue, HTTP_REQUEST_ID requestId);
|
|
|
|
public:
|
|
HttpServerApi(const WString& _urlPrefix, bool _respondToOptions);
|
|
~HttpServerApi();
|
|
|
|
HttpServerApi(const HttpServerApi&) = delete;
|
|
HttpServerApi(HttpServerApi&&) = delete;
|
|
HttpServerApi& operator=(const HttpServerApi&) = delete;
|
|
HttpServerApi& operator=(HttpServerApi&&) = delete;
|
|
|
|
void Start();
|
|
void Stop();
|
|
bool IsStopped();
|
|
HANDLE GetHttpRequestQueue() const;
|
|
|
|
Nullable<WString> GetUtf8Body(PHTTP_REQUEST pRequest);
|
|
static ULONG SendResponse(HANDLE httpRequestQueue, HTTP_REQUEST_ID requestId, const HttpServerResponse& response);
|
|
static void SendResponseUtf8(HANDLE httpRequestQueue, HTTP_REQUEST_ID requestId, WString body);
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\HTTPSERVER.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
HttpServer
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_HTTPSERVER
|
|
#define VCZH_INTERPROCESS_WINDOWS_HTTPSERVER
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
|
|
class HttpServer;
|
|
|
|
class HttpServerConnection : public Object, public virtual INetworkProtocolConnection
|
|
{
|
|
friend class HttpServer;
|
|
protected:
|
|
HttpServer* server = nullptr;
|
|
WString guid;
|
|
INetworkProtocolCallback* callback = nullptr;
|
|
|
|
SpinLock lockQueuedStrings;
|
|
collections::List<WString> queuedStrings;
|
|
|
|
SpinLock pendingRequestLock;
|
|
HTTP_REQUEST_ID httpPendingRequestId = HTTP_NULL_ID;
|
|
collections::List<WString> pendingRequestsToSend;
|
|
bool submittingResponse = false;
|
|
collections::List<WString> responsesToSubmit;
|
|
|
|
// All following functions must be called inside SPIN_LOCK(pendingRequestLock)
|
|
void OnCancelCurrentHttpRequestForPendingRequest();
|
|
void OnNewHttpRequestForPendingRequest(HTTP_REQUEST_ID httpRequestId);
|
|
|
|
WString SubmitResponse(PHTTP_REQUEST pRequest);
|
|
|
|
public:
|
|
void InstallCallback(INetworkProtocolCallback* _callback) override;
|
|
void BeginReadingLoopUnsafe() override;
|
|
void SendString(const WString& str) override;
|
|
void Stop() override;
|
|
|
|
static WString GenerateNewGuid();
|
|
};
|
|
|
|
class HttpServer : public HttpServerApi, public virtual INetworkProtocolServer
|
|
{
|
|
friend class HttpServerConnection;
|
|
using ConnectionMap = collections::Dictionary<WString, Ptr<HttpServerConnection>>;
|
|
protected:
|
|
WString baseUrl;
|
|
WString urlConnect;
|
|
WString urlRequestPrefix;
|
|
WString urlResponsePrefix;
|
|
|
|
// covers connections
|
|
SpinLock lockConnections;
|
|
ConnectionMap connections;
|
|
|
|
/***********************************************************************
|
|
HttpServer (BeginReadingLoopUnsafe)
|
|
***********************************************************************/
|
|
|
|
protected:
|
|
|
|
|
|
/***********************************************************************
|
|
HttpServer (HttpServerApi)
|
|
***********************************************************************/
|
|
|
|
protected:
|
|
|
|
void OnHttpRequestReceived(PHTTP_REQUEST pRequest) override;
|
|
void OnHttpServerStopping() override;
|
|
|
|
/***********************************************************************
|
|
HttpServer
|
|
***********************************************************************/
|
|
|
|
public:
|
|
HttpServer(const WString _baseUrl, vint port);
|
|
~HttpServer();
|
|
|
|
WaitForClientResult OnClientConnected(INetworkProtocolConnection* connection) override;
|
|
void Start() override;
|
|
void Stop() override;
|
|
bool IsStopped() override;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***********************************************************************
|
|
.\NAMEDPIPE.WINDOWS.H
|
|
***********************************************************************/
|
|
/***********************************************************************
|
|
Vczh Library++ 3.0
|
|
Developer: Zihan Chen(vczh)
|
|
|
|
Interfaces:
|
|
NamedPipeServer
|
|
NamedPipeClient
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef VCZH_INTERPROCESS_WINDOWS_NAMEDPIPE
|
|
#define VCZH_INTERPROCESS_WINDOWS_NAMEDPIPE
|
|
|
|
|
|
namespace vl::inter_process
|
|
{
|
|
|
|
class NamedPipeServer;
|
|
|
|
class NamedPipeConnection : public Object, public virtual INetworkProtocolConnection
|
|
{
|
|
friend class NamedPipeServer;
|
|
// -----------------------------------------------------------------------
|
|
// Reading
|
|
// -----------------------------------------------------------------------
|
|
|
|
private:
|
|
class ReadWaitContext;
|
|
|
|
bool firstRead = true;
|
|
atomic_vint stopped = 0;
|
|
collections::Array<BYTE> bufferReadFile;
|
|
stream::MemoryStream streamReadFile;
|
|
std::atomic<ReadWaitContext*> readWaitContext = nullptr;
|
|
OVERLAPPED overlappedReadFile;
|
|
HANDLE hEventReadFile = INVALID_HANDLE_VALUE;
|
|
atomic_vint pendingCallbacks = 0;
|
|
EventObject eventPendingCallbacks;
|
|
|
|
void BeginReadingUnsafe();
|
|
void SubmitReadBufferUnsafe(vint bytes);
|
|
void EndReadingUnsafe();
|
|
void BeginPendingCallback();
|
|
void EndPendingCallback();
|
|
|
|
public:
|
|
void BeginReadingLoopUnsafe() override;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Writing
|
|
// -----------------------------------------------------------------------
|
|
private:
|
|
SpinLock lockWrite;
|
|
stream::MemoryStream streamWriteFile;
|
|
OVERLAPPED overlappedWriteFile;
|
|
HANDLE hEventWriteFile = INVALID_HANDLE_VALUE;
|
|
|
|
vint32_t WriteInt32ToStream(vint32_t number);
|
|
vint32_t WriteStringToStream(const WString& str);
|
|
void BeginSendStream();
|
|
void EndSendStream(vint32_t bytes);
|
|
|
|
protected:
|
|
void SendString(const WString& str) override;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Connection
|
|
// -----------------------------------------------------------------------
|
|
|
|
protected:
|
|
// NamedPipe doesn't support a single message that is larger than 64K
|
|
static constexpr vint32_t MaxMessageSize = 65536;
|
|
|
|
NamedPipeServer* server = nullptr;
|
|
INetworkProtocolCallback* callback = nullptr;
|
|
HANDLE hPipe = INVALID_HANDLE_VALUE;
|
|
|
|
void OnLocalError(const WString& errorMessage);
|
|
void OnDisconnected();
|
|
|
|
NamedPipeConnection(HANDLE _hPipe);
|
|
|
|
public:
|
|
~NamedPipeConnection();
|
|
|
|
void InstallCallback(INetworkProtocolCallback* _callback) override;
|
|
void Stop() override;
|
|
};
|
|
|
|
class NamedPipeServer : public Object, public virtual INetworkProtocolServer
|
|
{
|
|
friend class NamedPipeConnection;
|
|
protected:
|
|
class PendingConnection : public Object
|
|
{
|
|
public:
|
|
class ConnectWaitContext;
|
|
|
|
NamedPipeServer* server = nullptr;
|
|
Ptr<NamedPipeConnection> connection;
|
|
std::atomic<ConnectWaitContext*> connectWaitContext = nullptr;
|
|
OVERLAPPED overlappedConnect;
|
|
HANDLE hEventConnect = INVALID_HANDLE_VALUE;
|
|
atomic_vint pendingCallbacks = 0;
|
|
EventObject eventPendingCallbacks;
|
|
|
|
PendingConnection(NamedPipeServer* _server, Ptr<NamedPipeConnection> _connection);
|
|
~PendingConnection();
|
|
|
|
void Stop();
|
|
void BeginPendingCallback();
|
|
void EndPendingCallback();
|
|
};
|
|
|
|
static HANDLE ServerCreatePipe(const WString& pipeName);
|
|
|
|
WString pipeName;
|
|
|
|
// covers started, stopped, connections and pendingConnections
|
|
SpinLock lockConnections;
|
|
bool started = false;
|
|
bool stopped = false;
|
|
collections::List<Ptr< NamedPipeConnection>> connections;
|
|
collections::List<Ptr<PendingConnection>> pendingConnections;
|
|
|
|
void BeginListening();
|
|
void CompletePendingConnection(Ptr<PendingConnection> pendingConnection, bool connected);
|
|
void CompletePendingConnection(PendingConnection* pendingConnection, bool connected);
|
|
|
|
public:
|
|
NamedPipeServer(const WString& _pipeName);
|
|
~NamedPipeServer();
|
|
|
|
WaitForClientResult OnClientConnected(INetworkProtocolConnection* connection) override;
|
|
void Start() override;
|
|
void Stop() override;
|
|
bool IsStopped() override;
|
|
};
|
|
|
|
class NamedPipeClient : public NamedPipeConnection, public virtual INetworkProtocolClient
|
|
{
|
|
protected:
|
|
static HANDLE ClientCreatePipe(const WString& pipeName);
|
|
ClientStatus status = ClientStatus::Ready;
|
|
|
|
public:
|
|
NamedPipeClient(const WString& _pipeName);
|
|
~NamedPipeClient();
|
|
|
|
INetworkProtocolConnection* GetConnection() override;
|
|
void WaitForServer() override;
|
|
ClientStatus GetStatus() override;
|
|
void Stop() override;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|