TOSAsync
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace LV::Server {
|
||||
|
||||
ContentEventController::ContentEventController(std::unique_ptr<RemoteClient> &&remote)
|
||||
ContentEventController::ContentEventController(RemoteClient_ptr &&remote)
|
||||
: Remote(std::move(remote))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
namespace LV::Server {
|
||||
|
||||
class RemoteClient;
|
||||
using RemoteClient_ptr = std::unique_ptr<RemoteClient, std::function<void(RemoteClient*)>>;
|
||||
class GameServer;
|
||||
class World;
|
||||
|
||||
@@ -162,7 +163,7 @@ private:
|
||||
|
||||
public:
|
||||
// Управляется сервером
|
||||
std::unique_ptr<RemoteClient> Remote;
|
||||
RemoteClient_ptr Remote;
|
||||
// Регионы сюда заглядывают
|
||||
// Каждый такт значения изменений обновляются GameServer'ом
|
||||
// Объявленная в чанках территория точно отслеживается (активная зона)
|
||||
@@ -173,7 +174,7 @@ public:
|
||||
// std::unordered_map<WorldId_t, std::vector<Pos::GlobalRegion>> SubscribedRegions;
|
||||
|
||||
public:
|
||||
ContentEventController(std::unique_ptr<RemoteClient> &&remote);
|
||||
ContentEventController(RemoteClient_ptr &&remote);
|
||||
|
||||
// Измеряется в чанках в радиусе (активная зона)
|
||||
uint16_t getViewRangeActive() const;
|
||||
|
||||
@@ -247,7 +247,7 @@ coro<> GameServer::pushSocketGameProtocol(tcp::socket socket, const std::string
|
||||
co_await Net::AsyncSocket::write<uint8_t>(socket, 0);
|
||||
|
||||
External.NewConnectedPlayers.lock_write()
|
||||
->push_back(std::make_unique<RemoteClient>(IOC, std::move(socket), username));
|
||||
->push_back(RemoteClient::Create(IOC, std::move(socket), username));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -333,7 +333,7 @@ void GameServer::run() {
|
||||
// Отключить вновь подключившихся
|
||||
auto lock = External.NewConnectedPlayers.lock_write();
|
||||
|
||||
for(std::unique_ptr<RemoteClient> &client : *lock) {
|
||||
for(RemoteClient_ptr &client : *lock) {
|
||||
client->shutdown(EnumDisconnect::ByInterface, ShutdownReason);
|
||||
}
|
||||
|
||||
@@ -449,8 +449,7 @@ void GameServer::stepPlayers() {
|
||||
if(!External.NewConnectedPlayers.no_lock_readable().empty()) {
|
||||
auto lock = External.NewConnectedPlayers.lock_write();
|
||||
|
||||
for(std::unique_ptr<RemoteClient> &client : *lock) {
|
||||
asio::co_spawn(IOC, client->run(), asio::detached);
|
||||
for(RemoteClient_ptr &client : *lock) {
|
||||
Game.CECs.push_back(std::make_unique<ContentEventController>(std::move(client)));
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class GameServer {
|
||||
|
||||
struct {
|
||||
Lockable<std::set<std::string>> ConnectedPlayersSet;
|
||||
Lockable<std::list<std::unique_ptr<RemoteClient>>> NewConnectedPlayers;
|
||||
Lockable<std::list<RemoteClient_ptr>> NewConnectedPlayers;
|
||||
|
||||
} External;
|
||||
|
||||
|
||||
@@ -3,28 +3,33 @@
|
||||
#include "Common/Net.hpp"
|
||||
#include "Server/Abstract.hpp"
|
||||
#include <boost/asio/error.hpp>
|
||||
#include <boost/chrono/duration.hpp>
|
||||
#include <boost/system/system_error.hpp>
|
||||
#include <exception>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include "World.hpp"
|
||||
#include "boost/asio/steady_timer.hpp"
|
||||
#include <Common/Packets.hpp>
|
||||
|
||||
|
||||
namespace LV::Server {
|
||||
|
||||
RemoteClient::~RemoteClient() {
|
||||
coro<> RemoteClient::asyncDestructor() {
|
||||
shutdown(EnumDisconnect::ByInterface, "~RemoteClient()");
|
||||
if(Socket.isAlive()) {
|
||||
Socket.closeRead();
|
||||
}
|
||||
|
||||
UseLock.wait_no_use();
|
||||
asio::steady_timer deadline(IOC);
|
||||
deadline.expires_after(std::chrono::seconds(1));
|
||||
|
||||
Socket.closeRead();
|
||||
co_await (deadline.async_wait(asio::use_awaitable) || RunCoro.async_wait());
|
||||
Socket.close();
|
||||
|
||||
co_await deadline.async_wait();
|
||||
}
|
||||
|
||||
coro<> RemoteClient::run() {
|
||||
auto useLock = UseLock.lock();
|
||||
RemoteClient::~RemoteClient() = default;
|
||||
|
||||
coro<> RemoteClient::run() {
|
||||
try {
|
||||
while(!IsGoingShutdown && IsConnected) {
|
||||
co_await readPacket(Socket);
|
||||
|
||||
@@ -3,12 +3,18 @@
|
||||
#include <TOSLib.hpp>
|
||||
#include <Common/Lockable.hpp>
|
||||
#include <Common/Net.hpp>
|
||||
#include <Common/Async.hpp>
|
||||
#include "Abstract.hpp"
|
||||
#include "Common/Packets.hpp"
|
||||
#include "Server/ContentEventController.hpp"
|
||||
#include "TOSAsync.hpp"
|
||||
#include "boost/asio/detached.hpp"
|
||||
#include "boost/asio/io_context.hpp"
|
||||
#include "boost/asio/use_awaitable.hpp"
|
||||
#include <Common/Abstract.hpp>
|
||||
#include <bitset>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
@@ -173,16 +179,16 @@ using EntityKey = std::tuple<WorldId_c, Pos::GlobalRegion>;
|
||||
|
||||
|
||||
|
||||
|
||||
class RemoteClient;
|
||||
using RemoteClient_ptr = std::unique_ptr<RemoteClient, std::function<void(RemoteClient*)>>;
|
||||
|
||||
/*
|
||||
Обработчик сокета клиента.
|
||||
Подписывает клиента на отслеживание необходимых ресурсов
|
||||
на основе передаваемых клиенту данных
|
||||
*/
|
||||
class RemoteClient {
|
||||
class RemoteClient : public TOS::IAsyncDestructible {
|
||||
TOS::Logger LOG;
|
||||
DestroyLock UseLock;
|
||||
Net::AsyncSocket Socket;
|
||||
bool IsConnected = true, IsGoingShutdown = false;
|
||||
|
||||
@@ -264,20 +270,32 @@ class RemoteClient {
|
||||
ResourceRequest NextRequest;
|
||||
std::vector<Net::Packet> SimplePackets;
|
||||
|
||||
TOS::WaitableCoro RunCoro;
|
||||
|
||||
public:
|
||||
const std::string Username;
|
||||
Pos::Object CameraPos = {0, 0, 0};
|
||||
ToServer::PacketQuat CameraQuat = {0};
|
||||
|
||||
public:
|
||||
private:
|
||||
|
||||
RemoteClient(asio::io_context &ioc, tcp::socket socket, const std::string username)
|
||||
: LOG("RemoteClient " + username), Socket(ioc, std::move(socket)), Username(username)
|
||||
: IAsyncDestructible(ioc), LOG("RemoteClient " + username), Socket(ioc, std::move(socket)),
|
||||
Username(username), RunCoro(ioc)
|
||||
{
|
||||
RunCoro.co_spawn(run());
|
||||
}
|
||||
|
||||
~RemoteClient();
|
||||
|
||||
virtual coro<> asyncDestructor() override;
|
||||
coro<> run();
|
||||
|
||||
public:
|
||||
static RemoteClient_ptr Create(asio::io_context &ioc, tcp::socket socket, const std::string username) {
|
||||
return createUnique<>(ioc, new RemoteClient(ioc, std::move(socket), username));
|
||||
}
|
||||
|
||||
virtual ~RemoteClient();
|
||||
|
||||
void shutdown(EnumDisconnect type, const std::string reason);
|
||||
bool isConnected() { return IsConnected; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user