Вопрос пользователя касается проблемы подключения клиент-серверной архитектуры на основе Datasnap, где клиентом является приложение на Android, а сервер запущен на ПК. При потере связи Wi-Fi между устройствами клиент замирает на время, превышающее установленные тайм-ауты, что приводит к неудобствам для пользователя и в некоторых случаях к сбою приложения.
Описание проблемного сценария
Клиент подключается к серверу через Wi-Fi, используя Datasnap для обмена данными. На стороне сервера используется TSQLConnection с драйвером Firebird и включенным режимом сохранения соединения. Серверный контейнер настроен с Queuesize: 100 и ChannelresponseTimeout: 3000. Транспорт TDSTCPServerTransport работает на порту 211 с настройками буфера и пула потоков.
На стороне клиента используется TSQLConnection с драйвером Datasnap и установленными ConnectTimeout:2000 и CommunicationTimeOut:5000. Пример кода клиента включает функцию TFrm_Principal.GetServerMethods1Client, которая управляет подключением к серверу, и функцию TServerMethods2Client.validaEstado, выполняющую проверку состояния на стороне сервера.
Подтвержденный ответ
Проблема заключается в том, что, несмотря на установленные тайм-ауты, клиентское приложение продолжает ожидать ответа от сервера даже после истечения заданных временных ограничений. Это происходит из-за использования блокирующих сокетов, которые не предназначены для быстрой проверки состояния соединения. Пока не произойдет внутренний таймаут в библиотеке сокетов, клиент не сможет определить, что соединение потеряно.
Альтернативный ответ и решение
Для решения проблемы можно использовать следующий подход:
Создать на стороне сервера функцию CheckCon(), которая не выполняет никаких действий, но дает клиенту возможность "стучать" по серверу и проверить, активен ли канал связи.
На стороне клиента обернуть вызов CheckCon() в блок try...except, чтобы перехватить возможные исключения, связанные с ошибками сокетов (EIdSocketError).
При возникновении исключения инициировать автоматическое переподключение к серверу.
Таким образом, пользователь сможет избежать длительного ожидания ответа от сервера и автоматически восстановит соединение в случае его потери. Это решение не устраняет задержку, связанную с внутренним таймаутом Windows WinSock, но позволяет минимизировать время простоя приложения.
Пример кода для функции CheckCon()
function TServerMethods1.CheckCon: Boolean;
begin
// Функция не выполняет никаких действий
Result := True;
end;
Пример клиентского кода для проверки соединения
procedure TFrm_Principal.CheckServerConnection;
begin
try
FServerMethods1Client.CheckCon;
except
on E: EIdSocketError do
begin
// Обработка ошибки сокета и переподключение
Conexion.Close;
Conexion.Open;
end;
end;
end;
Регулярный вызов этой функции CheckServerConnection на стороне клиента позволит своевременно обнаруживать потерю соединения и переподключаться к серверу.
Заключение
Использование функции CheckCon на стороне сервера в сочетании с обработкой исключений на стороне клиента позволит улучшить надежность и удобство использования клиент-серверной архитектуры на основе Datasnap.
Проблема связана с обработкой потери соединения Wi-Fi в клиент-серверной архитектуре, где клиент - приложение на Android, использующее Datasnap, а сервер - на ПК с драйвером Firebird.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.