2013-05-23 3 views
2

Я создаю приложение с недействительными в реальном времени с помощью сокета, а пока у меня что-то работает. Кажется, он перестает работать после перезапуска моего сервера (heartbeat больше не посылает). В процессе пытается найти лекарство, я понял, что не в полной мере понять всю концепцию, поэтому я решил опубликовать несколько вопросов здесь:Как подключиться к сокету после перезагрузки сервера

  1. Сейчас в заряда повторного подключения? Это клиент?
  2. Должны ли обе стороны (клиент и сервер) что-то сделать для поддержки механизма повторного подключения?
  3. Это вопрос с бонусом - как я могу добиться избыточности сокетов (возможность использования нескольких серверов). Должен ли я хранить все подключения в хранилище сеансов (redis)? Как обрабатывать повторные подключения в этом сценарии?

Я стараюсь держать этот вопрос вообще, а в случае, если вы заинтересованы, мое приложение написано в Flex и использует FlashSocket.IO для подключения к серверу (Tornado + Tornadio2 + tornadoredis)

ответ

2
  • Кто в заряде повторного подключения? Это клиент?

Да.

  • ли обе стороны (клиент и сервер) должны делать что-то для того, чтобы поддерживать механизм повторного соединения?

Сервер должен делать то, что он сделал в первую очередь: принять соединение. Клиент также должен делать то, что он сделал в первую очередь: создать соединение.

  • Это бонус вопрос - Как я могу добиться торцевого избыточности (возможность использовать более одного сервера).

Подключиться к другому серверу, когда первый не удался.

Должен ли я поддерживать все подключения в хранилище сеансов (redis)?

Нет. Это было бы просто отключение соединений.

Как обрабатывать повторные соединения в этом сценарии?

Точно так же вы обрабатываете их в любом сценарии. Просто подключитесь к клиенту. Но если у вас есть несколько отказоустойчивых серверов, вы не захотите повторно подключиться к тому, что просто не удалось, вы бы хотели создать новое соединение с другим членом группы серверов отказоустойчивости.

+0

Спасибо за сжатый ответ EJP. Это имеет смысл ... Как клиент знает, когда соединение было удалено? Тайм-аут, если нет биения в течение x секунд? – Ofir

+0

@Ofir Клиент получит таймаут чтения, если вы его установили, или «сброс соединения» при записи. – EJP

-1

Как правило, клиент несет ответственность за обнаружение и повторное подключение, если это необходимо. В зависимости от состояния, совместно используемого между клиентом и сервером, у обоих могут быть некоторые процедуры восстановления «перезагрузки», например, если клиент держит блокировку на сервере, тогда сервер должен освободить блокировку на отключении клиента, а клиенту придется приобрести новую блокировку. Это сильно зависит от того, что делают ваш клиент и сервер. Если вы хотите иметь распределенную/кластерную службу, то большинство из них по-прежнему верны. Это намного сложнее, поскольку состояние сервера разделяется между серверами, и вам нужно синхронизировать его. Возможно, вы не хотите, чтобы это реализовать на себя и использовать один из существующих решений - Redis, MongoDB, Apache-зоопарка ....

+0

Спасибо Тигран. Я не знаком с розетками. Можете ли вы подробно остановиться на этом? – Ofir

+0

Нет такой вещи, как блокировка гнезда. Я не вижу, как это отвечает на любой из ваших вопросов. -1 – EJP

+0

@EJP никто не говорит о замках сокетов. Любая база данных будет откатывать незавершенные транзакции и блокировки таблиц при отключении клиента. – kofemann

0

Для всех, кто приходит на это, самый простой способ узнать, был ли сокет закрыт, - это когда send() или recv() возвращают 0 (или -1). Тем не менее, я думаю, что также можно отправить() 0 байт, после чего recv() может технически по-прежнему возвращать 0, но оставаться открытым.

Я думаю, вы могли бы справиться с этой ситуацией, подождав несколько секунд и снова попробовав send(). Если он действительно был закрыт, и вы пытаетесь отправить() данные по сокету, то вы вернете -1. Если он снова был равен нулю, то это означает, что конец recv() не имеет памяти для того, чтобы буфер принимал что-либо.

Смежные вопросы