mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-08-03 06:08:39 +00:00
fix:forward情况下,connectto里面固定延时1000不合理,有的手机卡,需要2000甚至更高,改为定时重试策略
This commit is contained in:
parent
f5a9a399f0
commit
08da6cfbc1
2 changed files with 101 additions and 63 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue