While the peer does not drain its receive buffer, every forwarded packet would re-stall the reader thread for up to writeTimeout(), so a queued Disconnect frame could wait behind the whole backlog. Remember a stalled target (send slower than 2 s) and drop data for a short cooldown instead of stalling; keep dispatcher writes bounded at 3 s. Control frames (Connected/Disconnected) are unaffected.
55 lines
1.7 KiB
C++
55 lines
1.7 KiB
C++
#ifndef DISPATCHERCLIENT_H
|
|
#define DISPATCHERCLIENT_H
|
|
|
|
#include "picloudtcp.h"
|
|
#include "piethernet.h"
|
|
#include "pistreampacker.h"
|
|
|
|
|
|
class DispatcherClient: public PIObject {
|
|
PIOBJECT(DispatcherClient)
|
|
|
|
public:
|
|
DispatcherClient(PIEthernet * eth_, int id);
|
|
~DispatcherClient();
|
|
void start();
|
|
void close();
|
|
void stop();
|
|
void sendConnected(uint client_id);
|
|
void sendDisconnected(uint client_id);
|
|
void sendData(const PIByteArray & data);
|
|
void sendDataToClient(const PIByteArray & data, uint client_id);
|
|
void authorise(bool ok);
|
|
bool isAuthorised() const { return authorised; }
|
|
// forwarding to this connection stalled (peer not draining the send
|
|
// buffer) recently: drop data instead of stalling the reader thread
|
|
bool isWriteStalled() const { return (PISystemTime::current().toMilliseconds() - write_stalled_at) < 5000.0; }
|
|
void markWriteStalled() { write_stalled_at = PISystemTime::current().toMilliseconds(); }
|
|
PICloud::TCP::Role role() const { return tcp.role(); }
|
|
PIString address();
|
|
uint clientId() const { return client_id; }
|
|
EVENT1(disconnectEvent, DispatcherClient *, client)
|
|
EVENT2(registerServer, const PIByteArray &, sname, DispatcherClient *, client)
|
|
EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client)
|
|
EVENT1(dataReaded, PIByteArray &, ba)
|
|
EVENT2(dataReadedServer, uint, id, PIByteArray &, ba)
|
|
EVENT0(pingReceived)
|
|
|
|
PIObject::Connection connect_link;
|
|
|
|
private:
|
|
EVENT_HANDLER1(void, readed, PIByteArray &, data);
|
|
EVENT_HANDLER1(void, disconnected, bool, withError);
|
|
|
|
std::atomic_bool authorised;
|
|
std::atomic<double> write_stalled_at{0.0};
|
|
PIEthernet * eth;
|
|
PIStreamPacker streampacker;
|
|
PICloud::TCP tcp;
|
|
PIMutex mutex_send;
|
|
uint client_id;
|
|
};
|
|
|
|
|
|
#endif // DISPATCHERCLIENT_H
|