我写了一个管理REST请求的类。
使用指定数量的QNetworkAccessManager发送请求。
for (int i = 0; i < m_network_size; i++) {
auto network = new QNetworkAccessManager(this);
connect(network, &QNetworkAccessManager::finished, this, &ValueUpdater::handle_rest_response);
m_network_list << network;
}
还可以使用SOCKS5 IPv4 / 6代理。
if (*m_is_use_proxy) {
network->setProxy(get_random_proxy());
}
const QNetworkProxy & ValueUpdater::get_random_proxy() const
{
const auto & list = (m_is_site_use_proxy_ipv6 && *m_is_use_proxy_ipv6) ? m_proxy_ipv6_list : m_proxy_ipv4_list;
const auto random_index = qrand() % list.size();
const auto & proxy = (list.isEmpty()) ? m_empty_proxy : list.at(random_index);
return proxy;
}
问题在于,使用IPv6代理时,大多数请求都返回操作取消的错误(QNetworkReply :: OperationCanceledError)。
使用IPv4代理时,效果很好。
发送请求的代码:
void ValueUpdater::send_rest_request_for_coin(const QString &coin)
{
const auto & request = m_builded_request_list.value(coin);
if (++m_current_network_index >= m_network_size) {
m_current_network_index = 0;
}
const auto & network = m_network_list.at(m_current_network_index);
if (*m_is_use_proxy) {
network->setProxy(get_random_proxy());
}
auto reply = network->sendCustomRequest(request.internal_request, request.method, request.data);
QTimer::singleShot(2000, reply, &QNetworkReply::abort);
m_request_list.insert(reply, coin);
}
句柄回复的代码:
void ValueUpdater::handle_rest_response(QNetworkReply *reply)
{
if (!m_request_list.contains(reply)) {
reply->deleteLater();
return;
}
const auto coin = m_request_list.value(reply);
const auto is_success = reply->isReadable() && reply->error() == QNetworkReply::NoError && reply->bytesAvailable() > 0;
if (is_success) {
try {
QByteArray response;
while (!reply->atEnd()) {
response.append(reply->read(1024));
}
emit getted_response(coin, response);
if (m_is_display_scan_speed && *m_is_display_scan_speed) {
qDebug() << "[Speed]" << m_updater_name << m_uptime_list[coin].elapsed() << "ms";
m_uptime_list[coin] = QTime::currentTime();
}
} catch (...) {
qWarning() << "Just message for read response error";
}
} else {
qWarning() << reply->errorString();
}
if (m_executed_coin_list.contains(coin)) {
if (*m_scan_delay > 0) {
QTimer::singleShot(*m_scan_delay, [this, coin]{
send_rest_request_for_coin(coin);
});
} else {
send_rest_request_for_coin(coin);
}
}
m_request_list.remove(reply);
reply->close();
reply->deleteLater();
}
请求发送了很多。例如,有100个延迟的50个请求。
我尝试使用ProxyFactory切换Ipv4 / 6代理,但出现相同的错误。
P.S。 IPv6代理看起来像IPv4代理(xxx.xxx.xxx.xxx:port)。也许在代理服务器上,它们更改为IPv6格式。