Вызов OnFailure и IOException, но данные опубликованы
Это пример моего сетевого запроса
networkAPI.postData(myData).enqueue(new Callback<MyResponse>() {
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if (response.code() == 201) {
// success
}
}
@Override
public void onFailure(Call<MyResponse> call, Throwable t) {
}
});
Это запрос, который я должен вызывать только один раз, поскольку у меня есть один раз используемый код ваучера. Если я onFailure
свое сетевое подключение немедленно или если он немедленно отключится после вызова этого метода, то он перейдет к методу onFailure
с IOException
в throwable, который обычно ссылается на ошибку соединения. Но точка - это данные, отправленные на сервер, и код ваучера был использован, и Проблема заключается в onFailure
метод onFailure
был вызван.
Я уверен, что это не ошибка синтаксического анализа, поэтому я также попытался использовать Void
. Почему onResponse
не вызывается даже после публикации данных. Как преодолеть такую ситуацию?
Ответы
Ответ 1
Я не знаю, что ваш сервер, но в С# WebApi, на стороне сервера, вы можете проверить, все ли подключен клиент через Response.IsClientConnected
но этот флаг предназначен только для изящных отключений tcp, которые я считаю. Это не сработает, если клиент внезапно отключит свой интернет. Это просто из-за характера http (и лежащего в основе tcp)
Кроме того, я считаю, что стоит упомянуть, что всегда есть возможность запроса на сервер, но ответ не доходит до клиента. Просто нет способа гарантировать, что сервер не будет обрабатывать ваучер без успешного ответа клиенту. Клиент может отправить запрос, и как только вы будете готовы вернуть код состояния 200, клиент может отключиться. Это всегда следует учитывать при разработке веб-сервисов.
Самое лучшее, что нужно сделать, - дать клиенту возможность просмотреть прошлые погашенные ваучеры. Или на странице свежий или что-то, что вы можете автоматически проверить, была ли попытка повторного покушения на ваучер (через другой метод webservice) и отобразить ответ соответствующим образом.
Ответ 2
Я думаю, что модифицированные методы работают так, как ожидалось. Может случиться так, что вы разместили данные на своем сервере, и даже если интернет подключен, ваше серверное приложение занимает слишком много времени для обработки запроса, и как только сервер откликнется на успешный статус, запрос на стороне приложения истечет, Дело в том, что есть несколько таких случаев, в которых вы можете столкнуться с одной и той же проблемой.
Я могу придумать изящное решение этой конкретной проблемы, создав обращение к серверу-клиенту с использованием ваучера. Вы можете подумать о настройке локальной базы данных (это может быть любой механизм хранения, который можно обрабатывать локально), отслеживая коды ваучеров, которые вы пытались использовать до сих пор. В этом случае, когда запрос инициируется, флаг будет генерироваться локально, и при получении успешного ответа со стороны сервера флаг очищается.
Итак, каковы преимущества использования этого специального флага, указывающего, используется ли ваучер или нет? Главное преимущество заключается в том, что вы можете синхронизировать статус использования ваучера позже при получении трансляции, когда ваш интернет снова подключен. Вы можете рассмотреть возможность проверки флажка также при запуске приложения для синхронизации между сервером и клиентом в случае открытия любого предыдущего флага.
Ключевой идеей моего ответа является создание механизма установления связи между сервером и клиентом, в котором вы можете подтвердить, пользуется ли ваучер или нет.
Ответ 3
Мое случайное предположение состоит в том, что ваш ответ изменился динамически (может быть даже нулевым) в вашем конкретном сценарии ошибок. Поскольку вы ожидаете объект типа MyResponse
, когда возвращается динамически измененный ответ, ваш модифицированный вызов не сможет обрабатывать ответ и, следовательно, переходит к методу onFailure
. В этом случае ваши данные будут отправляться на ваш сервер, тогда как дооснащение onFailure
в onFailure
Possible Solution
Сначала попробуйте выяснить ответ в случае возникновения конкретной ошибки и попытаться создать для него модель (используйте void
для null
)
Попробуйте выполнить динамический анализ json, используя десериализатор для обработки динамического ответа на ошибку и правильного ответа во время выполнения. Следовательно, используя десериализатор, вы можете сделать свой ответ об ошибке (случай, когда данные отправляются) также отображаются в onResponse
Ответ 4
В соответствии с вопросом, который, как я полагаю, вы правильно размещаете данные в сети, и когда сервер пытается дать вам ответ, ваша система теряет соединение из-за сбоя сети, а модификация дает обратный вызов отказа.
Решение
Вы можете вызвать диалог api retry, когда выполнение завершится неудачей из-за сбоя сети и попросит пользователя снова отправить api и получить ответ правильно. Поэтому до тех пор, пока пользователю не будет предоставлен соответствующий ответ, он будет заблокирован, чтобы двигаться дальше.
Ответ 5
Это скорее внутренняя проблема ИМО. Такие задачи должны выполняться как транзакция и должны выполняться только в самом конце.
Если вам нужен точный результат, у вас есть функции выключения и игнорирование пользовательского прерывания (в PHP. Я считаю, что на других платформах будут подобные вещи), чтобы выполнить действие. Я предпочитаю первое.
Вот пример псевдо-кода для PHP.
/**
Define a global variable to identify whether the execution completed
successfully or an error (such as client disconnection) occurred
*/
$isProgramExecutionSuccessful = FALSE;
/**
shutdown function to execute finally
*/
function onShutdown() {
$error = error_get_last();
if ( $isProgramExecutionSuccessful == TRUE ) {
// commit transactions here
}
}
/**
Register shutdown function
*/
register_shutdown_function('onShutdown');
//Do database operations as transactions here
/**
At the end flag execution as successful
*/
$isProgramExecutionSuccessful = TRUE;