fix:forward情况下,connectto里面固定延时1000不合理,有的手机卡,需要2000甚至更高,改为定时重试策略

This commit is contained in:
Barry 2019-06-20 15:59:46 +08:00
commit 08da6cfbc1
2 changed files with 101 additions and 63 deletions

View file

@ -20,7 +20,7 @@ Server::Server(QObject *parent) : QObject(parent)
QTcpSocket* tmp = m_serverSocket.nextPendingConnection(); QTcpSocket* tmp = m_serverSocket.nextPendingConnection();
if (dynamic_cast<VideoSocket*>(tmp)) { if (dynamic_cast<VideoSocket*>(tmp)) {
m_videoSocket = dynamic_cast<VideoSocket*>(tmp); m_videoSocket = dynamic_cast<VideoSocket*>(tmp);
if (!m_videoSocket->isValid() || !readInfo(m_deviceName, m_deviceSize)) { if (!m_videoSocket->isValid() || !readInfo(m_videoSocket, m_deviceName, m_deviceSize)) {
stop(); stop();
emit connectToResult(false); emit connectToResult(false);
} }
@ -164,63 +164,7 @@ bool Server::connectTo()
return true; return true;
} }
// device server need time to start startConnectTimeoutTimer();
// TODO:电脑配置太低的话这里有可能时间不够导致连接太早安卓监听socket还没有建立
// 后续研究其他办法
// wait for devices server start
QTimer::singleShot(1000, this, [this](){
QString deviceName;
QSize deviceSize;
bool success = false;
// video socket
m_videoSocket = new VideoSocket();
m_videoSocket->connectToHost(QHostAddress::LocalHost, m_params.localPort);
if (!m_videoSocket->waitForConnected(1000)) {
stop();
qWarning("video socket connect to server failed");
emit connectToResult(false, "", QSize());
return false;
}
// control socket
m_controlSocket = new QTcpSocket();
m_controlSocket->connectToHost(QHostAddress::LocalHost, m_params.localPort);
if (!m_controlSocket->waitForConnected(1000)) {
stop();
qWarning("control socket connect to server failed");
emit connectToResult(false, "", QSize());
return false;
}
if (QTcpSocket::ConnectedState == m_videoSocket->state()) {
// connect will success even if devices offline, recv data is real connect success
// because connect is to pc adb server
m_videoSocket->waitForReadyRead(1000);
// devices will send 1 byte first on tunnel forward mode
QByteArray data = m_videoSocket->read(1);
if (!data.isEmpty() && readInfo(deviceName, deviceSize)) {
success = true;
} else {
qWarning("video socket connect to server read device info failed");
success = false;
}
} else {
qWarning("connect to server failed");
m_videoSocket->deleteLater();
success = false;
}
if (success) {
// we don't need the adb tunnel anymore
disableTunnelForward();
m_tunnelEnabled = false;
} else {
stop();
}
emit connectToResult(success, deviceName, deviceSize);
});
return true; return true;
} }
@ -229,6 +173,8 @@ void Server::timerEvent(QTimerEvent *event)
if (event && m_acceptTimeoutTimer == event->timerId()) { if (event && m_acceptTimeoutTimer == event->timerId()) {
stopAcceptTimeoutTimer(); stopAcceptTimeoutTimer();
emit connectToResult(false, "", QSize()); emit connectToResult(false, "", QSize());
} else if (event && m_connectTimeoutTimer == event->timerId()) {
onConnectTimer();
} }
} }
@ -317,14 +263,14 @@ bool Server::startServerByStep()
return stepSuccess; return stepSuccess;
} }
bool Server::readInfo(QString &deviceName, QSize &size) bool Server::readInfo(VideoSocket* videoSocket, QString &deviceName, QSize &size)
{ {
unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4]; unsigned char buf[DEVICE_NAME_FIELD_LENGTH + 4];
if (m_videoSocket->bytesAvailable() <= (DEVICE_NAME_FIELD_LENGTH + 4)) { if (videoSocket->bytesAvailable() <= (DEVICE_NAME_FIELD_LENGTH + 4)) {
m_videoSocket->waitForReadyRead(300); videoSocket->waitForReadyRead(300);
} }
qint64 len = m_videoSocket->read((char*)buf, sizeof(buf)); qint64 len = videoSocket->read((char*)buf, sizeof(buf));
if (len < DEVICE_NAME_FIELD_LENGTH + 4) { if (len < DEVICE_NAME_FIELD_LENGTH + 4) {
qInfo("Could not retrieve device information"); qInfo("Could not retrieve device information");
return false; return false;
@ -352,6 +298,93 @@ void Server::stopAcceptTimeoutTimer()
} }
} }
void Server::startConnectTimeoutTimer()
{
stopConnectTimeoutTimer();
m_connectTimeoutTimer = startTimer(100);
}
void Server::stopConnectTimeoutTimer()
{
if (m_connectTimeoutTimer) {
killTimer(m_connectTimeoutTimer);
m_connectTimeoutTimer = 0;
}
m_connectCount = 0;
}
void Server::onConnectTimer()
{
// device server need time to start
// 这里连接太早时间不够导致安卓监听socket还没有建立readInfo会失败所以采取定时重试策略
// 每隔100ms尝试一次最多尝试100次
QString deviceName;
QSize deviceSize;
bool success = false;
VideoSocket* videoSocket = new VideoSocket();
videoSocket->connectToHost(QHostAddress::LocalHost, m_params.localPort);
if (!videoSocket->waitForConnected(1000)) {
// 连接到adb很快的这里失败不重试
m_connectCount = 10;
qWarning("video socket connect to server failed");
goto result;
}
QTcpSocket *controlSocket = new QTcpSocket();
controlSocket->connectToHost(QHostAddress::LocalHost, m_params.localPort);
if (!controlSocket->waitForConnected(1000)) {
// 连接到adb很快的这里失败不重试
m_connectCount = 10;
qWarning("control socket connect to server failed");
goto result;
}
if (QTcpSocket::ConnectedState == videoSocket->state()) {
// connect will success even if devices offline, recv data is real connect success
// because connect is to pc adb server
videoSocket->waitForReadyRead(1000);
// devices will send 1 byte first on tunnel forward mode
QByteArray data = videoSocket->read(1);
if (!data.isEmpty() && readInfo(videoSocket, deviceName, deviceSize)) {
success = true;
goto result;
} else {
qWarning("video socket connect to server read device info failed, try again");
goto result;
}
} else {
qWarning("connect to server failed");
m_connectCount = 10;
goto result;
}
result:
if (success) {
stopConnectTimeoutTimer();
m_videoSocket = videoSocket;
m_controlSocket = controlSocket;
// we don't need the adb tunnel anymore
disableTunnelForward();
m_tunnelEnabled = false;
emit connectToResult(success, deviceName, deviceSize);
return;
}
if (videoSocket) {
videoSocket->deleteLater();
}
if (controlSocket) {
controlSocket->deleteLater();
}
if (10 <= m_connectCount++) {
stopConnectTimeoutTimer();
stop();
emit connectToResult(false);
}
}
void Server::onWorkProcessResult(AdbProcess::ADB_EXEC_RESULT processResult) void Server::onWorkProcessResult(AdbProcess::ADB_EXEC_RESULT processResult)
{ {
if (sender() == &m_workProcess) { if (sender() == &m_workProcess) {

View file

@ -65,9 +65,12 @@ private:
bool disableTunnelForward(); bool disableTunnelForward();
bool execute(); bool execute();
bool startServerByStep(); bool startServerByStep();
bool readInfo(QString& deviceName, QSize& size); bool readInfo(VideoSocket* videoSocket, QString& deviceName, QSize& size);
void startAcceptTimeoutTimer(); void startAcceptTimeoutTimer();
void stopAcceptTimeoutTimer(); void stopAcceptTimeoutTimer();
void startConnectTimeoutTimer();
void stopConnectTimeoutTimer();
void onConnectTimer();
private: private:
QString m_serverPath = ""; QString m_serverPath = "";
@ -79,6 +82,8 @@ private:
bool m_tunnelEnabled = false; bool m_tunnelEnabled = false;
bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse" bool m_tunnelForward = false; // use "adb forward" instead of "adb reverse"
quint32 m_acceptTimeoutTimer = 0; quint32 m_acceptTimeoutTimer = 0;
quint32 m_connectTimeoutTimer = 0;
quint32 m_connectCount = 0;
QString m_deviceName = ""; QString m_deviceName = "";
QSize m_deviceSize = QSize(); QSize m_deviceSize = QSize();
ServerParams m_params; ServerParams m_params;