That way, the RemotePeer subclasses don't all need to connect to the
signal themselves; also, we can make sure in a central place that
socket data is processed even the socket was handed over to the peer
with unhandled data still in its buffer.
Instead of handling the signal directly, RemotePeer subclasses need
to implement the onSocketDataAvailable() method.
{
_stream.setDevice(socket);
_stream.setVersion(QDataStream::Qt_4_2);
{
_stream.setDevice(socket);
_stream.setVersion(QDataStream::Qt_4_2);
-
- connect(socket, SIGNAL(readyRead()), SLOT(socketDataAvailable()));
-void LegacyPeer::socketDataAvailable()
+void LegacyPeer::onSocketDataAvailable()
{
QVariant item;
while (readSocketData(item)) {
{
QVariant item;
while (readSocketData(item)) {
// only used in compat mode
void protocolVersionMismatch(int actual, int expected);
// only used in compat mode
void protocolVersionMismatch(int actual, int expected);
-private slots:
- void socketDataAvailable();
+protected slots:
+ void onSocketDataAvailable();
private:
bool readSocketData(QVariant &item);
private:
bool readSocketData(QVariant &item);
_lag(0)
{
socket->setParent(this);
_lag(0)
{
socket->setParent(this);
- connect(socket, SIGNAL(disconnected()), SIGNAL(disconnected()));
+ connect(socket, SIGNAL(readyRead()), SLOT(onSocketDataAvailable()));
+ connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onSocketError(QAbstractSocket::SocketError)));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onSocketError(QAbstractSocket::SocketError)));
+ connect(socket, SIGNAL(disconnected()), SIGNAL(disconnected()));
#ifdef HAVE_SSL
QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket);
#ifdef HAVE_SSL
QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket);
#endif
connect(_heartBeatTimer, SIGNAL(timeout()), SLOT(sendHeartBeat()));
#endif
connect(_heartBeatTimer, SIGNAL(timeout()), SLOT(sendHeartBeat()));
+
+ // It's possible that more data has already arrived during the handshake, so readyRead() wouldn't be triggered.
+ // However, we can't call a virtual function from the ctor, so let's do it asynchronously.
+ if (socket->bytesAvailable())
+ QTimer::singleShot(0, this, SLOT(onSocketDataAvailable()));
virtual void dispatch(const Protocol::HeartBeat &msg) = 0;
virtual void dispatch(const Protocol::HeartBeatReply &msg) = 0;
virtual void dispatch(const Protocol::HeartBeat &msg) = 0;
virtual void dispatch(const Protocol::HeartBeatReply &msg) = 0;
+protected slots:
+ virtual void onSocketDataAvailable() = 0;
+ virtual void onSocketStateChanged(QAbstractSocket::SocketState state);
+ virtual void onSocketError(QAbstractSocket::SocketError error);
+
private slots:
void sendHeartBeat();
void changeHeartBeatInterval(int secs);
private slots:
void sendHeartBeat();
void changeHeartBeatInterval(int secs);
- void onSocketStateChanged(QAbstractSocket::SocketState state);
- void onSocketError(QAbstractSocket::SocketError error);
private:
QTcpSocket *_socket;
private:
QTcpSocket *_socket;