Разъем не отключается при изменении подключения - PullRequest
8 голосов
/ 05 января 2010

Мое приложение чата подключается к серверу, и пользователь отправляет / получает информацию. При изменении соединения, такого как 3g-> wifi, wifi-> 3g, потеря соединения для передачи данных и т. Д., Гнездо иногда остается подключенным целую вечность до разъединения. В течение этого времени невозможно определить, активно ли соединение, кажется, что сообщения отправляются просто отлично. В других случаях при отправке сообщения оно выдает ошибку ввода-вывода и отключается.

Помимо реализации кода для обнаружения изменений соединения и соответствующего повторного подключения, возможно ли, чтобы сокет немедленно выдавал исключение ввода-вывода при изменении соединения?

Редактировать: я подключаюсь, используя следующий код:

Socket sock = new Socket();
sock.connect(new InetSocketAddress(getAddress(), getPort())), getTimeout());
//get bufferedReader and read until BufferedReader#readLine() returns null

Я не использую setSoTimeout, поскольку данные могут не передаваться в течение длительных периодов времени в зависимости от конфигурации удаленного сервера.

Ответы [ 3 ]

1 голос
/ 06 января 2010

Вы говорите о java.net.Socket соединении?Затем попробуйте setSoTimeout () .В противном случае укажите, как вы подключаетесь.

0 голосов
/ 15 января 2014

Как уже указывалось в предыдущих ответах, это общая проблема. Даже после отправки пользовательского «ping» может потребоваться некоторое время, пока сокет поймет, что основное соединение разорвано. Кроме того, обычные эхо-запросы довольно требовательны к энергопотреблению при использовании мобильных сетей 3-4G из-за их хвостовых состояний. Не делай этого!

Однако вы можете запросить уведомление об изменении соединения (последний раздел) и вручную закрыть / снова подключить сокет в соответствующем приемнике вещания. (РЕДАКТИРОВАТЬ: я вижу, вы уже узнали об этом; просто держать его здесь для полноты)

0 голосов
/ 09 января 2010

Это старая проблема, с которой я сталкивался несколько раз в мире баз данных.

Я использовал решение для управления соединением на уровне приложения. Я бы явно отправлял неактивное сообщение некоторого вида (например, SELECT 1 WHERE FALSE) по соединению так же часто, как пинг, и если это не удалось, я бы разорвал и восстановил соединение, возможно, на отказоустойчивый сервер, если оригинал не принимает соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...