[+] Broadcasts and client/server messages
[+] Async responses [+] AuRPC::SetRecommendedPipeLength
This commit is contained in:
parent
eb042e5a29
commit
aa7591967a
@ -8,6 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct AuRPCRequest;
|
struct AuRPCRequest;
|
||||||
|
struct AuIRPCSession;
|
||||||
|
|
||||||
AUE_DEFINE(ERPCRequestState, (
|
AUE_DEFINE(ERPCRequestState, (
|
||||||
ePending,
|
ePending,
|
||||||
@ -31,34 +32,56 @@ AUE_DEFINE(ERPCError, (
|
|||||||
|
|
||||||
struct AuRPCResponse
|
struct AuRPCResponse
|
||||||
{
|
{
|
||||||
virtual ~AuRPCResponse()
|
inline virtual ~AuRPCResponse()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
AuRPCResponse() : error(ERPCError::eNone)
|
inline AuRPCResponse() : error(ERPCError::eNone)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AuRPCResponse(ERPCError error) : error(error)
|
inline AuRPCResponse(ERPCError error) : error(error)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline AuByteBuffer *GetBuffer()
|
||||||
|
{
|
||||||
|
return this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ERPCError GetError()
|
||||||
|
{
|
||||||
|
return this->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetError(ERPCError error)
|
||||||
|
{
|
||||||
|
this->error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend struct AuRPCResponseOwned;
|
||||||
|
friend struct AuRPCServerChannel;
|
||||||
|
friend struct AuRPCClientChannel;
|
||||||
|
friend struct AuRPCPipe;
|
||||||
|
friend struct AuRPCServer;
|
||||||
|
|
||||||
ERPCError error;
|
ERPCError error;
|
||||||
AuUInt64 cookie {};
|
AuUInt64 cookie {};
|
||||||
AuByteBuffer *message {};
|
AuByteBuffer *message {};
|
||||||
|
|
||||||
void Deserialize()
|
inline void Deserialize()
|
||||||
{
|
{
|
||||||
this->error = AuStaticCast<ERPCError>(message->Read<AuUInt8>());
|
this->error = AuStaticCast<ERPCError>(message->Read<AuUInt8>());
|
||||||
this->cookie = message->Read<AuUInt64>();
|
this->cookie = message->Read<AuUInt64>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrepareMessage()
|
inline void PrepareMessage()
|
||||||
{
|
{
|
||||||
message->Write<AuUInt8>(0);
|
message->Write<AuUInt8>(0);
|
||||||
message->Write<AuUInt64>(this->cookie);
|
message->Write<AuUInt64>(this->cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteError()
|
inline void WriteError()
|
||||||
{
|
{
|
||||||
message->Write<AuUInt8>(AuStaticCast<AuUInt8>(this->error));
|
message->Write<AuUInt8>(AuStaticCast<AuUInt8>(this->error));
|
||||||
message->Write<AuUInt64>(this->cookie);
|
message->Write<AuUInt64>(this->cookie);
|
||||||
@ -69,7 +92,7 @@ struct AuRPCResponseOwned : AuRPCResponse
|
|||||||
{
|
{
|
||||||
AuSPtr<AuByteBuffer> buffer;
|
AuSPtr<AuByteBuffer> buffer;
|
||||||
|
|
||||||
void PrepareResponse(AuUInt8 type)
|
inline void PrepareResponse(AuUInt8 type)
|
||||||
{
|
{
|
||||||
buffer = AuMakeShared<AuByteBuffer>();
|
buffer = AuMakeShared<AuByteBuffer>();
|
||||||
SysAssert(buffer);
|
SysAssert(buffer);
|
||||||
@ -78,7 +101,7 @@ struct AuRPCResponseOwned : AuRPCResponse
|
|||||||
buffer->Write(type);
|
buffer->Write(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeWrite()
|
inline void FinalizeWrite()
|
||||||
{
|
{
|
||||||
auto length = buffer->writePtr - buffer->base;
|
auto length = buffer->writePtr - buffer->base;
|
||||||
buffer->writePtr = buffer->base;
|
buffer->writePtr = buffer->base;
|
||||||
@ -93,7 +116,14 @@ AUI_INTERFACE(AuRPCRequestCallback,
|
|||||||
|
|
||||||
AUI_INTERFACE(AuIRPCChannelCallbacks,
|
AUI_INTERFACE(AuIRPCChannelCallbacks,
|
||||||
AUI_METHOD(void, OnConnect, ()),
|
AUI_METHOD(void, OnConnect, ()),
|
||||||
AUI_METHOD(void, OnDisconnect, ())
|
AUI_METHOD(void, OnDisconnect, ()),
|
||||||
|
AUI_METHOD(void, OnBroadcast, (AuByteBuffer &, refReadOnly)),
|
||||||
|
AUI_METHOD(void, OnMessage, (AuByteBuffer &, refReadOnly))
|
||||||
|
);
|
||||||
|
|
||||||
|
AUI_INTERFACE(AuIRPCServerCallbacks,
|
||||||
|
AUI_METHOD(void, OnMessage, (AuSPtr<AuIRPCSession>, pClient,
|
||||||
|
AuByteBuffer &, refReadOnly))
|
||||||
);
|
);
|
||||||
|
|
||||||
struct AuIRPCRequest
|
struct AuIRPCRequest
|
||||||
@ -102,10 +132,17 @@ struct AuIRPCRequest
|
|||||||
virtual bool SetData(const AuMemoryViewRead &view) = 0;
|
virtual bool SetData(const AuMemoryViewRead &view) = 0;
|
||||||
virtual bool EmptyRequest() = 0;
|
virtual bool EmptyRequest() = 0;
|
||||||
|
|
||||||
virtual void SetCallback(AuSPtr<AuRPCRequestCallback> callback) = 0;
|
virtual void SetCallback(const AuSPtr<AuRPCRequestCallback> &callback) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AuIRPCClientChannel
|
struct AuIRPCSession
|
||||||
|
{
|
||||||
|
virtual AuUInt64 GetConnectTimeNS() = 0;
|
||||||
|
virtual void SendMessage(const AuMemoryViewRead &view) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AuIRPCClientChannel :
|
||||||
|
AuIRPCSession
|
||||||
{
|
{
|
||||||
virtual void Disconnect() = 0;
|
virtual void Disconnect() = 0;
|
||||||
virtual void SendRequest(AuSPtr<AuIRPCRequest> response) = 0;
|
virtual void SendRequest(AuSPtr<AuIRPCRequest> response) = 0;
|
||||||
@ -116,14 +153,19 @@ struct AuIRPCClientChannel
|
|||||||
struct AuIRPCService
|
struct AuIRPCService
|
||||||
{
|
{
|
||||||
virtual AuUInt32 GetId() = 0;
|
virtual AuUInt32 GetId() = 0;
|
||||||
virtual void Dispatch(AuRPCResponse &response, AuUInt32 id, AuByteBuffer& buffer) = 0;
|
virtual void Dispatch(const AuSPtr<AuRPCResponse> &pResponse,
|
||||||
|
AuUInt32 id,
|
||||||
|
AuByteBuffer &buffer,
|
||||||
|
AuSharedFuture<void> &refFuture) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AuIRPCServer :
|
||||||
struct AuIRPCServer
|
AuIPC::IExportableIPC
|
||||||
{
|
{
|
||||||
virtual bool RegisterService(const AuSPtr<AuIRPCService> service) = 0;
|
virtual bool RegisterService(const AuSPtr<AuIRPCService> &service) = 0;
|
||||||
virtual AuString ExportString() = 0;
|
virtual void BroadcastMessage(const AuMemoryViewRead &view) = 0;
|
||||||
|
virtual AuList<AuSPtr<AuIRPCSession>> GetClients() = 0;
|
||||||
|
virtual void SetCallbacks(const AuSPtr<AuIRPCServerCallbacks> &pCallbacks) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AuIRPC
|
struct AuIRPC
|
||||||
@ -133,6 +175,8 @@ struct AuIRPC
|
|||||||
|
|
||||||
virtual AuSPtr<AuIRPCServer> ToServer() = 0;
|
virtual AuSPtr<AuIRPCServer> ToServer() = 0;
|
||||||
virtual AuSPtr<AuIRPCClientChannel> Connect(const AuString& str) = 0;
|
virtual AuSPtr<AuIRPCClientChannel> Connect(const AuString& str) = 0;
|
||||||
|
|
||||||
|
virtual void SetRecommendedPipeLength(AuUInt32 uLength) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
AuSPtr<AuIRPCRequest> AuRPCNewRequest(AuUInt32 serviceId, AuUInt32 methodId);
|
AuSPtr<AuIRPCRequest> AuRPCNewRequest(AuUInt32 serviceId, AuUInt32 methodId);
|
||||||
|
@ -60,6 +60,11 @@ AuSPtr<AuIRPCClientChannel> AuRPC::Connect(const AuString& str)
|
|||||||
return eh;
|
return eh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuRPC::SetRecommendedPipeLength(AuUInt32 uLength)
|
||||||
|
{
|
||||||
|
this->optPipeLength = uLength;
|
||||||
|
}
|
||||||
|
|
||||||
AuSPtr<AuIRPC> AuRPCNewInstance()
|
AuSPtr<AuIRPC> AuRPCNewInstance()
|
||||||
{
|
{
|
||||||
return AuMakeShared<AuRPC>();
|
return AuMakeShared<AuRPC>();
|
||||||
|
@ -23,15 +23,18 @@ struct AuIRPCService;
|
|||||||
|
|
||||||
struct AuRPC : AuIRPC, AuEnableSharedFromThis<AuRPC>
|
struct AuRPC : AuIRPC, AuEnableSharedFromThis<AuRPC>
|
||||||
{
|
{
|
||||||
|
bool StartClient(AuAsync::WorkerPId_t worker) override;
|
||||||
|
bool StartServer(AuAsync::WorkerPId_t worker) override;
|
||||||
|
|
||||||
bool StartClient(AuAsync::WorkerPId_t worker);
|
AuSPtr<AuIRPCServer> ToServer() override;
|
||||||
bool StartServer(AuAsync::WorkerPId_t worker);
|
AuSPtr<AuIRPCClientChannel> Connect(const AuString &str);
|
||||||
|
void SetRecommendedPipeLength(AuUInt32 uLength) override;
|
||||||
AuSPtr<AuIRPCServer> ToServer();
|
|
||||||
AuSPtr<AuIRPCClientChannel> Connect(const AuString& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend struct AuRPCPipe;
|
||||||
|
friend struct AuRPCServerChannel;
|
||||||
|
|
||||||
|
AuOptional<AuUInt32> optPipeLength;
|
||||||
AuAsync::WorkerPId_t pinnedClientThread;
|
AuAsync::WorkerPId_t pinnedClientThread;
|
||||||
AuRPCServer server;
|
AuRPCServer server;
|
||||||
AuList<AuSPtr<AuRPCClientChannel>> clientChannels;
|
AuList<AuSPtr<AuRPCClientChannel>> clientChannels;
|
||||||
@ -39,12 +42,16 @@ private:
|
|||||||
|
|
||||||
AuSPtr<AuIO::IIOProcessor> GetRPCProcessor();
|
AuSPtr<AuIO::IIOProcessor> GetRPCProcessor();
|
||||||
|
|
||||||
static const auto kRequestConnect = 1;
|
static const auto kRequestConnect = 1u;
|
||||||
static const auto kRequestRPC = 2;
|
static const auto kRequestRPC = 2u;
|
||||||
|
|
||||||
static const auto kResponseConnectOK = 10;
|
static const auto kResponseConnectOK = 10u;
|
||||||
static const auto kResponseMulticonnect = 11;
|
static const auto kResponseMulticonnect = 11u;
|
||||||
static const auto kResponseRPC = 12;
|
static const auto kResponseRPC = 12u;
|
||||||
|
|
||||||
|
static const auto kGeneralBroadcast = 20u;
|
||||||
|
static const auto kGeneralClientMessage = 21u; // shared
|
||||||
|
static const auto kGeneralServerMessage = 21u; // shared
|
||||||
|
|
||||||
static const AuUInt8 kResponseError[512] = {0};
|
static const AuUInt8 kResponseError[512] = {0};
|
||||||
|
|
||||||
|
@ -11,6 +11,11 @@
|
|||||||
#include "AuRPCRequest.hpp"
|
#include "AuRPCRequest.hpp"
|
||||||
#include "AuRPCPipePacket.hpp"
|
#include "AuRPCPipePacket.hpp"
|
||||||
|
|
||||||
|
AuRPCClientChannel::AuRPCClientChannel(AuSPtr<AuRPC> parent) :
|
||||||
|
parent_(parent),
|
||||||
|
pipe_(this)
|
||||||
|
{ }
|
||||||
|
|
||||||
bool AuRPCClientChannel::OnConnect()
|
bool AuRPCClientChannel::OnConnect()
|
||||||
{
|
{
|
||||||
auto request = AuMakeShared<AuRPCRequest>();
|
auto request = AuMakeShared<AuRPCRequest>();
|
||||||
@ -46,6 +51,19 @@ void AuRPCClientChannel::SendRequest(AuSPtr<AuIRPCRequest> response2)
|
|||||||
this->pipe_.SendPacket(packet);
|
this->pipe_.SendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuUInt64 AuRPCClientChannel::GetConnectTimeNS()
|
||||||
|
{
|
||||||
|
return this->uConnectTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuRPCClientChannel::SendMessage(const AuMemoryViewRead &view)
|
||||||
|
{
|
||||||
|
auto pMessage = AuMakeSharedPanic<AuRPCRequest>();
|
||||||
|
pMessage->dataType = kGeneralServerMessage;
|
||||||
|
pMessage->SetData(view);
|
||||||
|
this->SendRequest(pMessage);
|
||||||
|
}
|
||||||
|
|
||||||
AuSPtr<AuRPC> AuRPCClientChannel::ToContext()
|
AuSPtr<AuRPC> AuRPCClientChannel::ToContext()
|
||||||
{
|
{
|
||||||
return this->parent_;
|
return this->parent_;
|
||||||
@ -115,14 +133,40 @@ bool AuRPCClientChannel::OnDataAvailable(AuByteBuffer &view)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto oldLength = view.length;
|
auto oldLength = view.length;
|
||||||
|
auto oldWriteHead = view.writePtr;
|
||||||
view.length = (oldRead - view.base) + frameLength;
|
view.length = (oldRead - view.base) + frameLength;
|
||||||
|
view.writePtr = view.base + view.length;
|
||||||
response->message = &view;
|
response->message = &view;
|
||||||
|
|
||||||
response->Deserialize();
|
response->Deserialize();
|
||||||
this->ProcessResponse(response);
|
this->ProcessResponse(response);
|
||||||
|
|
||||||
view.readPtr = endPtr;
|
view.readPtr = endPtr;
|
||||||
|
view.writePtr = oldWriteHead;
|
||||||
|
view.length = oldLength;
|
||||||
|
}
|
||||||
|
else if (packetType == kGeneralBroadcast ||
|
||||||
|
packetType == kGeneralClientMessage)
|
||||||
|
{
|
||||||
|
auto oldLength = view.length;
|
||||||
|
auto oldWriteHead = view.writePtr;
|
||||||
|
view.length = (oldRead - view.base) + frameLength;
|
||||||
|
view.writePtr = view.base + view.length;
|
||||||
|
|
||||||
|
if (auto pCallbacks = this->callbacks_)
|
||||||
|
{
|
||||||
|
if (packetType == kGeneralBroadcast)
|
||||||
|
{
|
||||||
|
pCallbacks->OnBroadcast(view);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCallbacks->OnBroadcast(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.readPtr = endPtr;
|
||||||
|
view.writePtr = oldWriteHead;
|
||||||
view.length = oldLength;
|
view.length = oldLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +188,8 @@ void AuRPCClientChannel::FatalIOError()
|
|||||||
|
|
||||||
void AuRPCClientChannel::ProcessConnectionOK()
|
void AuRPCClientChannel::ProcessConnectionOK()
|
||||||
{
|
{
|
||||||
|
this->uConnectTime_ = AuTime::SteadyClockNS();
|
||||||
|
|
||||||
auto re = AuExchange(this->outstandingRequests, AuList<AuSPtr<AuRPCRequest>>{});
|
auto re = AuExchange(this->outstandingRequests, AuList<AuSPtr<AuRPCRequest>>{});
|
||||||
|
|
||||||
if (this->callbacks_)
|
if (this->callbacks_)
|
||||||
|
@ -10,11 +10,12 @@
|
|||||||
#include "AuRPCChannel.hpp"
|
#include "AuRPCChannel.hpp"
|
||||||
#include "AuRPCPipe.hpp"
|
#include "AuRPCPipe.hpp"
|
||||||
|
|
||||||
struct AuRPCClientChannel : AuRPCChannel, AuIRPCClientChannel, AuEnableSharedFromThis<AuRPCClientChannel>
|
struct AuRPCClientChannel :
|
||||||
|
AuRPCChannel,
|
||||||
|
AuIRPCClientChannel,
|
||||||
|
AuEnableSharedFromThis<AuRPCClientChannel>
|
||||||
{
|
{
|
||||||
AuRPCClientChannel(AuSPtr<AuRPC> parent) : parent_(parent), pipe_(this)
|
AuRPCClientChannel(AuSPtr<AuRPC> parent);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Init(const AuString& ipc);
|
bool Init(const AuString& ipc);
|
||||||
void Finalize();
|
void Finalize();
|
||||||
@ -24,6 +25,9 @@ struct AuRPCClientChannel : AuRPCChannel, AuIRPCClientChannel, AuEnableSharedFro
|
|||||||
|
|
||||||
void FatalIOError();
|
void FatalIOError();
|
||||||
|
|
||||||
|
virtual AuUInt64 GetConnectTimeNS() override;
|
||||||
|
virtual void SendMessage(const AuMemoryViewRead &view) override;
|
||||||
|
|
||||||
virtual AuSPtr<AuRPC> ToContext() override;
|
virtual AuSPtr<AuRPC> ToContext() override;
|
||||||
virtual bool OnConnect() override;
|
virtual bool OnConnect() override;
|
||||||
virtual void OnDisconnect(bool error) override;
|
virtual void OnDisconnect(bool error) override;
|
||||||
@ -37,7 +41,6 @@ struct AuRPCClientChannel : AuRPCChannel, AuIRPCClientChannel, AuEnableSharedFro
|
|||||||
virtual bool IsConnected() override;
|
virtual bool IsConnected() override;
|
||||||
virtual void SetCallbacks(const AuSPtr<AuIRPCChannelCallbacks> &callbacks) override;
|
virtual void SetCallbacks(const AuSPtr<AuIRPCChannelCallbacks> &callbacks) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool bConnectingAlternate_{};
|
bool bConnectingAlternate_{};
|
||||||
bool bConnected_{};
|
bool bConnected_{};
|
||||||
@ -45,4 +48,5 @@ private:
|
|||||||
AuSPtr<AuIRPCChannelCallbacks> callbacks_;
|
AuSPtr<AuIRPCChannelCallbacks> callbacks_;
|
||||||
AuRPCPipe pipe_;
|
AuRPCPipe pipe_;
|
||||||
AuSPtr<AuRPC> parent_;
|
AuSPtr<AuRPC> parent_;
|
||||||
|
AuUInt64 uConnectTime_ {};
|
||||||
};
|
};
|
@ -13,11 +13,10 @@
|
|||||||
#include "AuRPCChannel.hpp"
|
#include "AuRPCChannel.hpp"
|
||||||
#include "AuRPCClientChannel.hpp"
|
#include "AuRPCClientChannel.hpp"
|
||||||
|
|
||||||
bool AuRPCPipe::SendPacket(const AuRPCPipePacket &packet)
|
struct RPCTransaction :
|
||||||
|
AuIO::IAsyncFinishedSubscriber,
|
||||||
|
AuEnableSharedFromThis<RPCTransaction>
|
||||||
{
|
{
|
||||||
|
|
||||||
struct RPCTransaction : AuIO::IAsyncFinishedSubscriber, AuEnableSharedFromThis<RPCTransaction>
|
|
||||||
{
|
|
||||||
AuSPtr<AuIO::IAsyncTransaction> transaction;
|
AuSPtr<AuIO::IAsyncTransaction> transaction;
|
||||||
AuMemoryViewRead view;
|
AuMemoryViewRead view;
|
||||||
AuRPCPipePacket packet;
|
AuRPCPipePacket packet;
|
||||||
@ -87,8 +86,10 @@ bool AuRPCPipe::SendPacket(const AuRPCPipePacket &packet)
|
|||||||
packet.clientRequest->state = ERPCRequestState::eSent;
|
packet.clientRequest->state = ERPCRequestState::eSent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool AuRPCPipe::SendPacket(const AuRPCPipePacket &packet)
|
||||||
|
{
|
||||||
auto ioTransaction = this->pipe->NewAsyncTransaction();
|
auto ioTransaction = this->pipe->NewAsyncTransaction();
|
||||||
if (!ioTransaction)
|
if (!ioTransaction)
|
||||||
{
|
{
|
||||||
@ -107,17 +108,41 @@ bool AuRPCPipe::SendPacket(const AuRPCPipePacket &packet)
|
|||||||
|
|
||||||
transactionObject->transaction->SetCallback(transactionObject);
|
transactionObject->transaction->SetCallback(transactionObject);
|
||||||
|
|
||||||
|
AuWorkerPId_t pid;
|
||||||
|
if (packet.clientChannel)
|
||||||
|
{
|
||||||
|
pid = this->channel->ToContext()->pinnedClientThread;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pid = this->channel->ToContext()->server.worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid != AuAsync::GetCurrentWorkerPId())
|
||||||
|
{
|
||||||
|
AuAsync::NewWorkFunction(pid, [=]()
|
||||||
|
{
|
||||||
transactionObject->SendClient();
|
transactionObject->SendClient();
|
||||||
|
|
||||||
if (!transactionObject->transaction->StartWrite(0, AuSPtr<AuMemoryViewRead>(transactionObject->SharedFromThis(), &transactionObject->view)))
|
if (!transactionObject->transaction->StartWrite(0, AuSPtr<AuMemoryViewRead>(transactionObject->SharedFromThis(), &transactionObject->view)))
|
||||||
{
|
{
|
||||||
transactionObject->Fail();
|
transactionObject->Fail();
|
||||||
}
|
}
|
||||||
|
})->Dispatch();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transactionObject->SendClient();
|
||||||
|
|
||||||
|
if (!transactionObject->transaction->StartWrite(0, AuSPtr<AuMemoryViewRead>(transactionObject->SharedFromThis(), &transactionObject->view)))
|
||||||
|
{
|
||||||
|
transactionObject->Fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AuRPCPipe::~AuRPCPipe()
|
AuRPCPipe::~AuRPCPipe()
|
||||||
{
|
{
|
||||||
Deinit();
|
Deinit();
|
||||||
@ -247,9 +272,12 @@ bool AuRPCPipe::Init(const AuString& str)
|
|||||||
return true;// WaitForOtherEnd();
|
return true;// WaitForOtherEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuRPCPipe::Init()
|
bool AuRPCPipe::Init(AuOptional<AuUInt32> optLength)
|
||||||
{
|
{
|
||||||
this->pipe = AuIPC::NewPipe();
|
this->pipe = optLength ?
|
||||||
|
AuIPC::NewPipeEx(optLength.value()) :
|
||||||
|
AuIPC::NewPipe();
|
||||||
|
|
||||||
if (!this->pipe)
|
if (!this->pipe)
|
||||||
{
|
{
|
||||||
SysPushErrorIO("Couldn't spare the resources required for an IPC pipe");
|
SysPushErrorIO("Couldn't spare the resources required for an IPC pipe");
|
||||||
|
@ -41,7 +41,7 @@ struct AuRPCPipe : AuIO::IIOBufferedStreamAvailable, AuIO::IIOSimpleEventListene
|
|||||||
bool SendPacket(const AuRPCPipePacket& packet);
|
bool SendPacket(const AuRPCPipePacket& packet);
|
||||||
|
|
||||||
bool Init(const AuString& str);
|
bool Init(const AuString& str);
|
||||||
bool Init();
|
bool Init(AuOptional<AuUInt32> optLength);
|
||||||
bool WaitForOtherEnd();
|
bool WaitForOtherEnd();
|
||||||
void Deinit();
|
void Deinit();
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ bool AuRPCRequest::SetData(const AuMemoryViewRead& view)
|
|||||||
return bool(data);
|
return bool(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuRPCRequest::SetCallback(AuSPtr<AuRPCRequestCallback> callback)
|
void AuRPCRequest::SetCallback(const AuSPtr<AuRPCRequestCallback> &callback)
|
||||||
{
|
{
|
||||||
this->callback = callback;
|
this->callback = callback;
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ void AuRPCRequest::WriteHeaderConnect()
|
|||||||
void AuRPCRequest::WriteRPCHeader()
|
void AuRPCRequest::WriteRPCHeader()
|
||||||
{
|
{
|
||||||
this->data.Write<AuUInt32>(this->packetLength);
|
this->data.Write<AuUInt32>(this->packetLength);
|
||||||
this->data.Write<AuUInt8>(kRequestRPC);
|
this->data.Write<AuUInt8>(this->dataType);
|
||||||
this->data.Write<AuUInt32>(this->serviceId);
|
this->data.Write<AuUInt32>(this->serviceId);
|
||||||
this->data.Write<AuUInt32>(this->methodId);
|
this->data.Write<AuUInt32>(this->methodId);
|
||||||
this->data.Write<AuUInt64>(AuUInt64(AuUInt(this)));
|
this->data.Write<AuUInt64>(AuUInt64(AuUInt(this)));
|
||||||
|
@ -13,12 +13,13 @@ struct AuRPCRequest : AuIRPCRequest
|
|||||||
ERPCRequestState state{};
|
ERPCRequestState state{};
|
||||||
AuUInt32 methodId{};
|
AuUInt32 methodId{};
|
||||||
AuSPtr<AuRPCRequestCallback> callback;
|
AuSPtr<AuRPCRequestCallback> callback;
|
||||||
|
int dataType { kRequestRPC };
|
||||||
AuUInt64 cookie {};
|
AuUInt64 cookie {};
|
||||||
|
|
||||||
bool SetData(const AuByteBuffer& toRead) override;
|
bool SetData(const AuByteBuffer& toRead) override;
|
||||||
bool SetData(const AuMemoryViewRead& view) override;
|
bool SetData(const AuMemoryViewRead& view) override;
|
||||||
|
|
||||||
void SetCallback(AuSPtr<AuRPCRequestCallback> callback) override;
|
void SetCallback(const AuSPtr<AuRPCRequestCallback> &callback) override;
|
||||||
|
|
||||||
bool EmptyRequest() override;
|
bool EmptyRequest() override;
|
||||||
|
|
||||||
|
@ -19,16 +19,9 @@ bool AuRPCServer::Init(AuRPC *parent, AuAsync::WorkerPId_t worker)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this->lock = AuThreadPrimitives::RWLockUnique();
|
|
||||||
if (!this->lock)
|
|
||||||
{
|
|
||||||
SysPushErrorMem();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this->worker = worker;
|
this->worker = worker;
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
this->channel = NewChannel();
|
this->channel = NewChannel(false);
|
||||||
|
|
||||||
if (!this->channel)
|
if (!this->channel)
|
||||||
{
|
{
|
||||||
@ -39,7 +32,7 @@ bool AuRPCServer::Init(AuRPC *parent, AuAsync::WorkerPId_t worker)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuRPCServer::RegisterService(const AuSPtr<AuIRPCService> service)
|
bool AuRPCServer::RegisterService(const AuSPtr<AuIRPCService> &service)
|
||||||
{
|
{
|
||||||
if (!service)
|
if (!service)
|
||||||
{
|
{
|
||||||
@ -51,7 +44,57 @@ bool AuRPCServer::RegisterService(const AuSPtr<AuIRPCService> service)
|
|||||||
return AuTryInsert(this->serviceTable, service->GetId(), service);
|
return AuTryInsert(this->serviceTable, service->GetId(), service);
|
||||||
}
|
}
|
||||||
|
|
||||||
AuString AuRPCServer::ExportString()
|
void AuRPCServer::BroadcastMessage(const AuMemoryViewRead &view)
|
||||||
|
{
|
||||||
|
AuList<AuSPtr<AuRPCServerChannel>> channels;
|
||||||
|
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(this->lock->AsReadable());
|
||||||
|
|
||||||
|
for (const auto &pChannel : this->channel->subchannels_)
|
||||||
|
{
|
||||||
|
if (pChannel)
|
||||||
|
{
|
||||||
|
if (!pChannel->isTempChannel_)
|
||||||
|
{
|
||||||
|
channels.push_back(pChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pMessage = AuMakeSharedPanic<AuRPCResponseOwned>();
|
||||||
|
pMessage->PrepareResponse(kGeneralBroadcast);
|
||||||
|
pMessage->buffer->Write(view.ptr, view.length);
|
||||||
|
pMessage->FinalizeWrite();
|
||||||
|
|
||||||
|
for (const auto &pChannel : channels)
|
||||||
|
{
|
||||||
|
pChannel->SendResponse(pMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuList<AuSPtr<AuIRPCSession>> AuRPCServer::GetClients()
|
||||||
|
{
|
||||||
|
AuList<AuSPtr<AuIRPCSession>> ret;
|
||||||
|
|
||||||
|
if (auto pChannel = this->channel)
|
||||||
|
{
|
||||||
|
for (const auto &pClientChannel : pChannel->subchannels_)
|
||||||
|
{
|
||||||
|
ret.push_back(pClientChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuRPCServer::SetCallbacks(const AuSPtr<AuIRPCServerCallbacks> &pCallbacks)
|
||||||
|
{
|
||||||
|
this->pCallbacks = pCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuString AuRPCServer::ExportToString()
|
||||||
{
|
{
|
||||||
return ToPrimaryChannel()->ExportString();
|
return ToPrimaryChannel()->ExportString();
|
||||||
}
|
}
|
||||||
@ -63,7 +106,7 @@ AuSPtr<AuRPCServerChannel> AuRPCServer::ToPrimaryChannel()
|
|||||||
return this->channel;
|
return this->channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->channel = NewChannel();
|
return this->channel = NewChannel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuRPCServer::Dispatch(AuRPCServerChannel *channel,
|
void AuRPCServer::Dispatch(AuRPCServerChannel *channel,
|
||||||
@ -72,28 +115,40 @@ void AuRPCServer::Dispatch(AuRPCServerChannel *channel,
|
|||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->lock->AsReadable());
|
AU_LOCK_GUARD(this->lock->AsReadable());
|
||||||
|
|
||||||
auto response = AuMakeShared<AuRPCResponseOwned>();
|
auto pResponse = AuMakeSharedPanic<AuRPCResponseOwned>();
|
||||||
SysAssert(response);
|
|
||||||
|
|
||||||
response->cookie = request->cookie;
|
pResponse->cookie = request->cookie;
|
||||||
response->PrepareResponse(kResponseRPC);
|
pResponse->PrepareResponse(kResponseRPC);
|
||||||
|
|
||||||
auto itr = this->serviceTable.find(request->serviceId);
|
auto itr = this->serviceTable.find(request->serviceId);
|
||||||
if (itr == this->serviceTable.end())
|
if (itr == this->serviceTable.end())
|
||||||
{
|
{
|
||||||
response->FinalizeWrite();
|
pResponse->FinalizeWrite();
|
||||||
channel->SendResponse(response);
|
channel->SendResponse(pResponse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response->PrepareMessage();
|
pResponse->PrepareMessage();
|
||||||
|
|
||||||
itr->second->Dispatch(*response, request->methodId, *buffer);
|
AuSharedFuture<void> refFuture;
|
||||||
|
itr->second->Dispatch(pResponse, request->methodId, *buffer, refFuture);
|
||||||
|
|
||||||
response->FinalizeWrite();
|
if (!refFuture)
|
||||||
channel->SendResponse(response);
|
{
|
||||||
|
pResponse->FinalizeWrite();
|
||||||
|
channel->SendResponse(pResponse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pShared = channel->SharedFromThis();
|
||||||
|
refFuture->OnComplete([=]()
|
||||||
|
{
|
||||||
|
pResponse->FinalizeWrite();
|
||||||
|
pShared->SendResponse(pResponse);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -102,7 +157,7 @@ void AuRPCServer::Dispatch(AuRPCServerChannel *channel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuRPCServerChannel> AuRPCServer::NewChannel()
|
AuSPtr<AuRPCServerChannel> AuRPCServer::NewChannel(bool bIsPrimary)
|
||||||
{
|
{
|
||||||
auto eh = AuMakeShared<AuRPCServerChannel>(this->parent->SharedFromThis(), AuSPtr<AuRPCServer>(this->parent->SharedFromThis(), this));
|
auto eh = AuMakeShared<AuRPCServerChannel>(this->parent->SharedFromThis(), AuSPtr<AuRPCServer>(this->parent->SharedFromThis(), this));
|
||||||
if (!eh)
|
if (!eh)
|
||||||
|
@ -13,21 +13,28 @@ struct AuRPCServerChannel;
|
|||||||
struct AuRPCServer : AuIRPCServer
|
struct AuRPCServer : AuIRPCServer
|
||||||
{
|
{
|
||||||
bool Init(AuRPC* parent, AuAsync::WorkerPId_t worker);
|
bool Init(AuRPC* parent, AuAsync::WorkerPId_t worker);
|
||||||
bool RegisterService(const AuSPtr<AuIRPCService> service) override;
|
bool RegisterService(const AuSPtr<AuIRPCService> &service) override;
|
||||||
|
void BroadcastMessage(const AuMemoryViewRead &view) override;
|
||||||
|
AuList<AuSPtr<AuIRPCSession>> GetClients() override;
|
||||||
|
void SetCallbacks(const AuSPtr<AuIRPCServerCallbacks> &pCallbacks) override;
|
||||||
|
|
||||||
AuString ExportString() override;
|
|
||||||
|
AuString ExportToString() override;
|
||||||
AuSPtr<AuRPCServerChannel> ToPrimaryChannel();
|
AuSPtr<AuRPCServerChannel> ToPrimaryChannel();
|
||||||
AuSPtr<AuRPCServerChannel> NewChannel();
|
AuSPtr<AuRPCServerChannel> NewChannel(bool bIsPrimary);
|
||||||
|
|
||||||
void Dispatch(AuRPCServerChannel *channel,
|
void Dispatch(AuRPCServerChannel *channel,
|
||||||
const AuSPtr<AuRPCRequest> &request,
|
const AuSPtr<AuRPCRequest> &request,
|
||||||
AuByteBuffer *buffer);
|
AuByteBuffer *buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend struct AuRPCServerChannel;
|
||||||
|
friend struct AuRPCPipe;
|
||||||
|
|
||||||
AuRPC* parent;
|
AuRPC* parent;
|
||||||
AuSPtr<AuRPCServerChannel> channel;
|
AuSPtr<AuRPCServerChannel> channel;
|
||||||
AuAsync::WorkerPId_t worker;
|
AuAsync::WorkerPId_t worker;
|
||||||
AuThreadPrimitives::RWLockUnique_t lock;
|
AuRWLock lock;
|
||||||
AuHashMap<AuUInt32, AuSPtr<AuIRPCService>> serviceTable;
|
AuHashMap<AuUInt32, AuSPtr<AuIRPCService>> serviceTable;
|
||||||
|
AuSPtr<AuIRPCServerCallbacks> pCallbacks;
|
||||||
};
|
};
|
@ -16,7 +16,12 @@ AuRPCServerChannel::AuRPCServerChannel(AuSPtr<AuRPC> parent, AuSPtr<AuRPCServer>
|
|||||||
pipe(this),
|
pipe(this),
|
||||||
server_(server)
|
server_(server)
|
||||||
{
|
{
|
||||||
|
this->uConnectTime_ = AuTime::SteadyClockNS();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuRPCServerChannel::~AuRPCServerChannel()
|
||||||
|
{
|
||||||
|
this->RemoveFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
AuSPtr<AuRPC> AuRPCServerChannel::ToContext()
|
AuSPtr<AuRPC> AuRPCServerChannel::ToContext()
|
||||||
@ -51,6 +56,24 @@ bool AuRPCServerChannel::OnConnect()
|
|||||||
void AuRPCServerChannel::OnDisconnect(bool error)
|
void AuRPCServerChannel::OnDisconnect(bool error)
|
||||||
{
|
{
|
||||||
RpcLogDebug("Server channel disconnected: {}", error);
|
RpcLogDebug("Server channel disconnected: {}", error);
|
||||||
|
this->RemoveFromParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuRPCServerChannel::RemoveFromParent()
|
||||||
|
{
|
||||||
|
if (auto pParent = this->server_)
|
||||||
|
{
|
||||||
|
AU_LOCK_GUARD(pParent->lock->AsWritable());
|
||||||
|
|
||||||
|
if (auto pChannel = pParent->channel)
|
||||||
|
{
|
||||||
|
AuRemoveIf(pChannel->subchannels_,
|
||||||
|
[=](AuSPtr<AuRPCServerChannel> pChannel) -> bool
|
||||||
|
{
|
||||||
|
return pChannel.get() == this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuRPCServerChannel::OnDataAvailable(AuByteBuffer& view)
|
bool AuRPCServerChannel::OnDataAvailable(AuByteBuffer& view)
|
||||||
@ -107,11 +130,31 @@ bool AuRPCServerChannel::OnDataAvailable(AuByteBuffer& view)
|
|||||||
request->cookie = view.Read<AuUInt64>();
|
request->cookie = view.Read<AuUInt64>();
|
||||||
|
|
||||||
auto oldLength = view.length;
|
auto oldLength = view.length;
|
||||||
|
auto oldWriteHead = view.writePtr;
|
||||||
view.length = (oldRead - view.base) + frameLength;
|
view.length = (oldRead - view.base) + frameLength;
|
||||||
|
view.writePtr = view.base + view.length;
|
||||||
|
|
||||||
this->server_->Dispatch(this, request, &view);
|
this->server_->Dispatch(this, request, &view);
|
||||||
|
|
||||||
view.readPtr = frameLength + oldRead;
|
view.readPtr = oldRead + frameLength;
|
||||||
|
view.writePtr = oldWriteHead;
|
||||||
|
view.length = oldLength;
|
||||||
|
}
|
||||||
|
else if (packetType == kGeneralServerMessage)
|
||||||
|
{
|
||||||
|
auto oldLength = view.length;
|
||||||
|
auto oldWriteHead = view.writePtr;
|
||||||
|
view.length = (oldRead - view.base) + frameLength;
|
||||||
|
view.writePtr = view.base + view.length;
|
||||||
|
|
||||||
|
if (auto pCallbacks = this->server_->pCallbacks)
|
||||||
|
{
|
||||||
|
pCallbacks->OnMessage(this->SharedFromThis(),
|
||||||
|
view);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.readPtr = oldRead + frameLength;
|
||||||
|
view.writePtr = oldWriteHead;
|
||||||
view.length = oldLength;
|
view.length = oldLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +164,20 @@ bool AuRPCServerChannel::OnDataAvailable(AuByteBuffer& view)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuUInt64 AuRPCServerChannel::GetConnectTimeNS()
|
||||||
|
{
|
||||||
|
return this->uConnectTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuRPCServerChannel::SendMessage(const AuMemoryViewRead &view)
|
||||||
|
{
|
||||||
|
auto pMessage = AuMakeSharedPanic<AuRPCResponseOwned>();
|
||||||
|
pMessage->PrepareResponse(kGeneralClientMessage);
|
||||||
|
pMessage->buffer->Write(view.ptr, view.length);
|
||||||
|
pMessage->FinalizeWrite();
|
||||||
|
this->SendResponse(pMessage);
|
||||||
|
}
|
||||||
|
|
||||||
void AuRPCServerChannel::SendConnectOK()
|
void AuRPCServerChannel::SendConnectOK()
|
||||||
{
|
{
|
||||||
RpcLogDebug("AuRPCServerChannel::SendConnectOK");
|
RpcLogDebug("AuRPCServerChannel::SendConnectOK");
|
||||||
@ -150,7 +207,7 @@ void AuRPCServerChannel::SendToNewChannel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
res->PrepareResponse(kResponseMulticonnect);
|
res->PrepareResponse(kResponseMulticonnect);
|
||||||
auto channel = this->server_->NewChannel();
|
auto channel = this->server_->NewChannel(false);
|
||||||
if (!channel)
|
if (!channel)
|
||||||
{
|
{
|
||||||
this->FatalError();
|
this->FatalError();
|
||||||
@ -178,5 +235,5 @@ void AuRPCServerChannel::FatalError()
|
|||||||
|
|
||||||
bool AuRPCServerChannel::Init()
|
bool AuRPCServerChannel::Init()
|
||||||
{
|
{
|
||||||
return this->pipe.Init();
|
return this->pipe.Init(this->parent->optPipeLength);
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,13 @@
|
|||||||
#include "AuRPCChannel.hpp"
|
#include "AuRPCChannel.hpp"
|
||||||
#include "AuRPCPipe.hpp"
|
#include "AuRPCPipe.hpp"
|
||||||
|
|
||||||
struct AuRPCServerChannel : AuRPCChannel
|
struct AuRPCServerChannel :
|
||||||
|
AuRPCChannel,
|
||||||
|
AuIRPCSession,
|
||||||
|
AuEnableSharedFromThis<AuRPCServerChannel>
|
||||||
{
|
{
|
||||||
AuRPCServerChannel(AuSPtr<AuRPC> parent, AuSPtr<AuRPCServer> server);
|
AuRPCServerChannel(AuSPtr<AuRPC> parent, AuSPtr<AuRPCServer> server);
|
||||||
|
~AuRPCServerChannel();
|
||||||
|
|
||||||
bool Init();
|
bool Init();
|
||||||
AuString ExportString();
|
AuString ExportString();
|
||||||
@ -24,6 +28,9 @@ struct AuRPCServerChannel : AuRPCChannel
|
|||||||
virtual void OnDisconnect(bool error) override;
|
virtual void OnDisconnect(bool error) override;
|
||||||
virtual bool OnDataAvailable(AuByteBuffer& view) override;
|
virtual bool OnDataAvailable(AuByteBuffer& view) override;
|
||||||
|
|
||||||
|
virtual AuUInt64 GetConnectTimeNS() override;
|
||||||
|
virtual void SendMessage(const AuMemoryViewRead &view) override;
|
||||||
|
|
||||||
void FatalError();
|
void FatalError();
|
||||||
|
|
||||||
void SendToNewChannel();
|
void SendToNewChannel();
|
||||||
@ -33,11 +40,16 @@ struct AuRPCServerChannel : AuRPCChannel
|
|||||||
{
|
{
|
||||||
this->isTempChannel_ = true;
|
this->isTempChannel_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoveFromParent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend struct AuRPCServer;
|
||||||
|
|
||||||
AuList<AuSPtr<AuRPCServerChannel>> subchannels_;
|
AuList<AuSPtr<AuRPCServerChannel>> subchannels_;
|
||||||
AuSPtr<AuRPCServer> server_;
|
AuSPtr<AuRPCServer> server_;
|
||||||
bool isTempChannel_ {};
|
bool isTempChannel_ {};
|
||||||
AuRPCPipe pipe;
|
AuRPCPipe pipe;
|
||||||
|
AuUInt64 uConnectTime_ {};
|
||||||
AuSPtr<AuRPC> parent;
|
AuSPtr<AuRPC> parent;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user