Skip to content

Commit e17bc84

Browse files
committed
Add server disconnection notice to client
1 parent b89ccd0 commit e17bc84

File tree

5 files changed

+71
-14
lines changed

5 files changed

+71
-14
lines changed

examples/clientServerLifeSimulator_004/client/main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,16 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
224224
fge::net::ClientStatus::NetworkStatus::DISCONNECTED);
225225
server._client.getStatus().resetTimeout();
226226
});
227+
server._onClientDisconnected.addLambda([&]([[maybe_unused]] fge::net::ClientSideNetUdp& client) {
228+
std::cout << "connection lost ! (disconnected from server)" << std::endl;
229+
230+
server.stop();
231+
mainScene->delAllObject(true);
232+
createConnectionWindow();
233+
server._client.getStatus().set(FGE_NET_STATUS_DEFAULT_STATUS,
234+
fge::net::ClientStatus::NetworkStatus::DISCONNECTED);
235+
server._client.getStatus().resetTimeout();
236+
});
227237

228238
auto const adapters = fge::net::Socket::getAdaptersInfo();
229239
for (auto const& adapter: adapters)

examples/clientServerLifeSimulator_004/server/main.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[])
367367
fge::Sleep(std::chrono::milliseconds(LIFESIM_SERVER_TICK));
368368
}
369369

370+
std::cout << "disconnecting clients" << std::endl;
371+
serverFlux->disconnectAllClients(std::chrono::milliseconds(2000));
372+
370373
std::cout << "shutdown ..." << std::endl;
371374
server.stop();
372375

includes/FastEngine/network/C_protocol.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ template<class... Args>
237237
{
238238
return std::make_shared<ProtocolPacket>(std::forward<Args>(args)...);
239239
}
240-
template<class... Args>
241240
[[nodiscard]] inline TransmitPacketPtr CreatePacket()
242241
{
243242
return std::make_shared<ProtocolPacket>(FGE_NET_BAD_ID);
@@ -261,6 +260,13 @@ enum InternalProtocolIds : ProtocolPacket::IdType
261260
NET_INTERNAL_ID_DISCONNECT
262261
};
263262

263+
[[nodiscard]] inline TransmitPacketPtr CreateDisconnectPacket()
264+
{
265+
auto packet = std::make_shared<ProtocolPacket>(NET_INTERNAL_ID_DISCONNECT);
266+
packet->doNotDiscard().doNotReorder();
267+
return packet;
268+
}
269+
264270
struct InternalFragmentedPacketData
265271
{
266272
uint8_t _fragmentTotal;

includes/FastEngine/network/C_server.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class FGE_API ServerNetFluxUdp : public NetFluxUdp
137137
[[nodiscard]] FluxProcessResults
138138
process(ClientSharedPtr& refClient, ReceivedPacketPtr& packet, bool allowUnknownClient);
139139

140+
void disconnectAllClients(std::chrono::milliseconds delay = std::chrono::milliseconds(0)) const;
141+
140142
ClientList _clients;
141143

142144
CallbackHandler<ClientSharedPtr const&> _onClientBadRealm;
@@ -333,6 +335,7 @@ class FGE_API ClientSideNetUdp : public NetFluxUdp
333335
Client _client; //But it is the server :O
334336

335337
CallbackHandler<ClientSideNetUdp&> _onClientTimeout;
338+
CallbackHandler<ClientSideNetUdp&> _onClientDisconnected;
336339

337340
private:
338341
void threadReception();

sources/network/C_server.cpp

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,22 @@ void ServerNetFluxUdp::processClients()
179179
{
180180
auto& client = it->second._client;
181181

182-
//Handle timeout
183-
if (client->getStatus().getNetworkStatus() == ClientStatus::NetworkStatus::TIMEOUT)
182+
//Handle bad clients
183+
auto const status = client->getStatus().getNetworkStatus();
184+
if (status == ClientStatus::NetworkStatus::DISCONNECTED)
184185
{
186+
auto tmpIdentity = it->first;
187+
auto tmpClient = std::move(it->second._client);
188+
it = this->_clients.remove(it, clientsLock);
189+
this->_onClientDisconnected.call(tmpClient, tmpIdentity);
185190
continue;
186191
}
187192

193+
//Handle timeout
194+
if (status == ClientStatus::NetworkStatus::TIMEOUT)
195+
{
196+
continue;
197+
}
188198
if (client->getStatus().isTimeout())
189199
{
190200
client->getStatus().setNetworkStatus(ClientStatus::NetworkStatus::TIMEOUT);
@@ -233,6 +243,12 @@ void ServerNetFluxUdp::processClients()
233243
}
234244
}
235245

246+
void ServerNetFluxUdp::disconnectAllClients(std::chrono::milliseconds delay) const
247+
{
248+
this->_clients.sendToAll(CreateDisconnectPacket());
249+
std::this_thread::sleep_for(delay);
250+
}
251+
236252
FluxProcessResults
237253
ServerNetFluxUdp::process(ClientSharedPtr& refClient, ReceivedPacketPtr& packet, bool allowUnknownClient)
238254
{
@@ -1035,37 +1051,39 @@ void ServerSideNetUdp::threadTransmission()
10351051

10361052
for (auto itClient = clients->begin(clientLock); itClient != clients->end(clientLock); ++itClient)
10371053
{
1038-
if (itClient->second._client->isPendingPacketsEmpty())
1054+
auto& client = itClient->second._client;
1055+
1056+
if (client->isPendingPacketsEmpty())
10391057
{
10401058
continue;
10411059
}
10421060

1043-
if (itClient->second._client->getLastPacketLatency() < itClient->second._client->getSTOCLatency_ms())
1061+
if (client->getLastPacketLatency() < client->getSTOCLatency_ms())
10441062
{
10451063
continue;
10461064
}
10471065

1048-
auto transmissionPacket = itClient->second._client->popPacket();
1066+
auto transmissionPacket = client->popPacket();
10491067

10501068
//Compression and applying options
1051-
if (!transmissionPacket->isFragmented() && itClient->second._client->getStatus().isInEncryptedState())
1069+
if (!transmissionPacket->isFragmented() && client->getStatus().isInEncryptedState())
10521070
{
1053-
transmissionPacket->applyOptions(*itClient->second._client);
1071+
transmissionPacket->applyOptions(*client);
10541072
if (!transmissionPacket->compress(compressor))
10551073
{
10561074
continue;
10571075
}
10581076
}
10591077
else
10601078
{
1061-
transmissionPacket->applyOptions(*itClient->second._client);
1079+
transmissionPacket->applyOptions(*client);
10621080
}
10631081

10641082
//MTU check
10651083
if (!transmissionPacket->isFragmented() &&
10661084
!transmissionPacket->checkFlags(FGE_NET_HEADER_DO_NOT_FRAGMENT_FLAG))
10671085
{
1068-
auto const mtu = itClient->second._client->getMTU();
1086+
auto const mtu = client->getMTU();
10691087

10701088
//Packet is not fragmented, we have to check is size
10711089
if (mtu == 0)
@@ -1082,7 +1100,7 @@ void ServerSideNetUdp::threadTransmission()
10821100
}
10831101
else
10841102
{
1085-
itClient->second._client->pushForcedFrontPacket(std::move(fragments[iFragment]));
1103+
client->pushForcedFrontPacket(std::move(fragments[iFragment]));
10861104
}
10871105
}
10881106
}
@@ -1093,18 +1111,26 @@ void ServerSideNetUdp::threadTransmission()
10931111
continue;
10941112
}
10951113

1114+
//Check if the packet is a disconnection packet
1115+
if (transmissionPacket->retrieveHeaderId().value() == NET_INTERNAL_ID_DISCONNECT)
1116+
{
1117+
client->getStatus().setNetworkStatus(ClientStatus::NetworkStatus::DISCONNECTED);
1118+
client->getStatus().setTimeout(FGE_NET_STATUS_DEFAULT_TIMEOUT);
1119+
client->clearPackets();
1120+
}
1121+
10961122
//Check if the packet must be encrypted
10971123
if (transmissionPacket->isMarkedForEncryption())
10981124
{
1099-
if (!CryptEncrypt(*itClient->second._client, *transmissionPacket))
1125+
if (!CryptEncrypt(*client, *transmissionPacket))
11001126
{
11011127
continue;
11021128
}
11031129
}
11041130

11051131
//Sending the packet
11061132
this->g_socket.sendTo(transmissionPacket->packet(), itClient->first._ip, itClient->first._port);
1107-
itClient->second._client->resetLastPacketTimePoint();
1133+
client->resetLastPacketTimePoint();
11081134
}
11091135
}
11101136

@@ -1309,9 +1335,9 @@ FluxProcessResults ClientSideNetUdp::process(ReceivedPacketPtr& packet)
13091335
if (this->_client.getStatus().isTimeout())
13101336
{
13111337
this->_client.getStatus().setNetworkStatus(ClientStatus::NetworkStatus::TIMEOUT);
1312-
this->_onClientTimeout.call(*this);
13131338
this->_g_remainingPackets = 0;
13141339
this->clearPackets();
1340+
this->_onClientTimeout.call(*this);
13151341
return FluxProcessResults::NOT_RETRIEVABLE;
13161342
}
13171343

@@ -1364,6 +1390,15 @@ FluxProcessResults ClientSideNetUdp::process(ReceivedPacketPtr& packet)
13641390
}
13651391
}
13661392

1393+
if (packet->retrieveHeaderId().value() == NET_INTERNAL_ID_DISCONNECT)
1394+
{
1395+
this->_client.getStatus().setNetworkStatus(ClientStatus::NetworkStatus::DISCONNECTED);
1396+
this->_g_remainingPackets = 0;
1397+
this->clearPackets();
1398+
this->_onClientDisconnected.call(*this);
1399+
return FluxProcessResults::NOT_RETRIEVABLE;
1400+
}
1401+
13671402
if (stat == PacketReorderer::Stats::WAITING_NEXT_REALM || stat == PacketReorderer::Stats::WAITING_NEXT_COUNTER)
13681403
{
13691404
this->_client.advanceLostPacketCount(); //We are missing a packet

0 commit comments

Comments
 (0)