Я написал класс, который управляет запросами 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();
}
Запросы отправляет много.Например, 50 запросов с задержкой 100 мс.
Я пытался использовать ProxyFactory для переключения прокси Ipv4 / 6, но получил ту же ошибку.
PS Прокси IPv6 выглядит как прокси IPv4 (xxx.xxx.xxx.xxx: порт).Возможно на прокси-сервере они меняют формат IPv6.