2022-07-02 22:08:52 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: AuRPCServer.cpp
|
|
|
|
Date: 2022-6-29
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#include <AuroraRuntime.hpp>
|
|
|
|
#include "AuRPC.hpp"
|
|
|
|
#include "AuRPCServer.hpp"
|
|
|
|
#include "AuRPCServerChannel.hpp"
|
|
|
|
#include "AuRPCRequest.hpp"
|
|
|
|
|
|
|
|
bool AuRPCServer::Init(AuRPC *parent, AuAsync::WorkerPId_t worker)
|
|
|
|
{
|
|
|
|
if (this->channel)
|
|
|
|
{
|
|
|
|
SysPushErrorGen("Double init");
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
this->worker = worker;
|
|
|
|
this->parent = parent;
|
2023-12-16 18:16:32 +00:00
|
|
|
this->channel = NewChannel(false);
|
2022-07-02 22:08:52 +00:00
|
|
|
|
|
|
|
if (!this->channel)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->channel->MakeTemp();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
bool AuRPCServer::RegisterService(const AuSPtr<AuIRPCService> &service)
|
2022-07-02 22:08:52 +00:00
|
|
|
{
|
|
|
|
if (!service)
|
|
|
|
{
|
|
|
|
SysPushErrorArg();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
AU_LOCK_GUARD(this->lock->AsWritable());
|
|
|
|
return AuTryInsert(this->serviceTable, service->GetId(), service);
|
|
|
|
}
|
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
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()
|
2022-07-02 22:08:52 +00:00
|
|
|
{
|
|
|
|
return ToPrimaryChannel()->ExportString();
|
|
|
|
}
|
|
|
|
|
|
|
|
AuSPtr<AuRPCServerChannel> AuRPCServer::ToPrimaryChannel()
|
|
|
|
{
|
|
|
|
if (this->channel)
|
|
|
|
{
|
|
|
|
return this->channel;
|
|
|
|
}
|
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
return this->channel = NewChannel(true);
|
2022-07-02 22:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuRPCServer::Dispatch(AuRPCServerChannel *channel,
|
|
|
|
const AuSPtr<AuRPCRequest> &request,
|
|
|
|
AuByteBuffer *buffer)
|
|
|
|
{
|
|
|
|
AU_LOCK_GUARD(this->lock->AsReadable());
|
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
auto pResponse = AuMakeSharedPanic<AuRPCResponseOwned>();
|
2022-07-02 22:08:52 +00:00
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
pResponse->cookie = request->cookie;
|
|
|
|
pResponse->PrepareResponse(kResponseRPC);
|
2022-07-02 22:08:52 +00:00
|
|
|
|
|
|
|
auto itr = this->serviceTable.find(request->serviceId);
|
|
|
|
if (itr == this->serviceTable.end())
|
|
|
|
{
|
2023-12-16 18:16:32 +00:00
|
|
|
pResponse->FinalizeWrite();
|
|
|
|
channel->SendResponse(pResponse);
|
2022-07-02 22:08:52 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2023-12-16 18:16:32 +00:00
|
|
|
pResponse->PrepareMessage();
|
2022-07-02 22:08:52 +00:00
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
AuSharedFuture<void> refFuture;
|
|
|
|
itr->second->Dispatch(pResponse, request->methodId, *buffer, refFuture);
|
2022-07-07 04:16:27 +00:00
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
if (!refFuture)
|
|
|
|
{
|
|
|
|
pResponse->FinalizeWrite();
|
|
|
|
channel->SendResponse(pResponse);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto pShared = channel->SharedFromThis();
|
|
|
|
refFuture->OnComplete([=]()
|
|
|
|
{
|
|
|
|
pResponse->FinalizeWrite();
|
|
|
|
pShared->SendResponse(pResponse);
|
|
|
|
});
|
|
|
|
}
|
2022-07-02 22:08:52 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
SysPushErrorCatch();
|
|
|
|
channel->FatalError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-16 18:16:32 +00:00
|
|
|
AuSPtr<AuRPCServerChannel> AuRPCServer::NewChannel(bool bIsPrimary)
|
2022-07-02 22:08:52 +00:00
|
|
|
{
|
|
|
|
auto eh = AuMakeShared<AuRPCServerChannel>(this->parent->SharedFromThis(), AuSPtr<AuRPCServer>(this->parent->SharedFromThis(), this));
|
|
|
|
if (!eh)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((this->worker.second != AuAsync::kThreadIdAny) &&
|
|
|
|
(this->worker == AuAsync::GetCurrentWorkerPId()))
|
|
|
|
{
|
|
|
|
if (!eh->Init())
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-09-22 03:45:57 +00:00
|
|
|
DispatchOn(this->worker, [&]()
|
2022-07-02 22:08:52 +00:00
|
|
|
{
|
|
|
|
if (!eh->Init())
|
|
|
|
{
|
|
|
|
eh.reset();
|
|
|
|
}
|
2023-09-22 03:45:57 +00:00
|
|
|
})->BlockUntilComplete();
|
2022-07-02 22:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return eh;
|
|
|
|
}
|