![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Столкнулся с проблемой, о которой раньше даже не думал: физический разрыв сокетного соединения. Программные отсоединения клиента (переход на др. страницу и т.п.) я предусмотрел, а вот о физическом разрыве не подумал. В результате физического разрыва получаю на сервере новый переподключившийся сокет от клиента и оборванный сокет, который однако же продолжает отсылать информацию, предназначенную клиенту, в никуда, т.к он идет в списке раньше.
Какие существуют методы контроля физического разрыва со стороны сервера? В первую очередь в голову приходит банальный пинг, но не хотелось бы нагружать соединение пустым катанием байт туда обратно. Таймаут может быть длительным без получения от клиента данных, поэтому тоже не подходит. Может есть что-то еще?
__________________
interplanety |
|
|||||
|
Цитата:
|
|
|||||
|
2 caseyryan
А какой интервал времени стоит на пинг? Ну, с какой частотой сервер пингует? upd: И все равно понять не могу, поможет ли мне пинг. Допустим сервер отправил пинговый байт в оба соединения, разорванное и нормальное. Из нормального ответ вернулся, значит все в порядке. Но из разорванного-то ответ не вернется, соответственно функция select не вернет мне этот сокет в списке готовых на чтение. Можно бегать по всему списку работающих сокетов, проверяя по времени, не вернулся ли ответ, скажем через минуту. Но тогда select теряет смысл. upd1: Пока в голову приходит только такой способ - хранить в связке с указателем на сокет id пользователя (что и так делается) и при попытке создания второго сокетного соединения с тем же id рубить первое. Проблемным останется момент, когда обрыв связи у пользователя произойдет до высылки им его id. Тогда в списке повиснет неидентифицированный сокет, но такие можно рубить допустим раз в час принудительно. В любом случае двух каналов для одного пользователя не будет и данные не будут улетать с сервера в пустоту.
__________________
interplanety Последний раз редактировалось Korchy; 14.10.2013 в 15:32. |
|
|||||
|
Цитата:
Поэтому у меня как у них 900 милисекунд (и 6000 на ожидание ответа). Но это значение указывается в xml файле настроек сервера, так что всегда можно легко поменять. Цитата:
), по этому событию экземпляр просто сносится из карты хэшей менеджером подключений, и дергается метод dispose() |
|
|||||
|
Цитата:
Я же отправив в оба сокета (разорванный и рабочий) пинг получу при следующем вызове select только рабочий. Разорванный как был неактивен, так им и остается. Наверное можно сделать, что при ответе в рабочем сокете сбросится таймер пинга, а в разорванном соотв-но он будет дальше расти и при последующих вызовах пинга в каждом сокете проверять не прошло ли время на пинг + время на ответ и обрывать если прошло. Хотелось бы получить проблемный сокет в селекте, но видимо это невозможно. Поэтому мне пока больше нравится вариант с проверкой по id. Так проверка будет выполняться только при коннекте, а не каждые 900 мс. Правда в таком случае, если пользователь запустит два окна, они будут рвать соединение друг у друга ![]()
__________________
interplanety |
|
|||||
|
Цитата:
Допустим клиент коннектится к серверу, при этом создается новый объект Client, через который и происходит все общение с flash клиентом. Он начинает через 900 милисекунд слать этому клиенту сообщение _hb (в независимости от того, шлются какие-то другие сообщения или нет). При отправке _hb сообщения, фиксируется время его отправки. С этого момента начинается ожидание ответа клиента. Если в течение 6000 милисекунд клиент ничего не ответил, соединение считается дохлым. Все ридеры и райтеры глушатся, и отправляется событие дисконнекта. Менеджер клиентов его получает, и сносит target клиент из общего списка. Таким образом в списке всегда только живые сокеты. Цитата:
|
|
|||||
|
Цитата:
. Я часто сумбурно излагаю, сорри.У вас есть список подключенных клиентов. Как у вас сервер понимает, что от клиента N пришли данные?
__________________
interplanety |
|
|||||
|
Я вот так и не врубился в проблему флеш сокета, если не пинговать и не слать данные, то время жизни подключения где то до 5-и минут, больше не живет
пинг прекрасно работал, но кушал канал, серверное время и вооще мешал спокойно спать ночами ![]() в итоге просто сделал микро-пинг с клиента, отсылал раз в две минуты один символ, сервер на него не реагирует, зато линк постоянно находится в "живом" состоянии. Со стороны сервера пинг не имел смысла, там разрыв "заснувшего" соединения почему то прекрасно отрабатывается, первая версия сервер-сокета была пхп, сейчас .net/c# |
|
|||||
|
Цитата:
1) Флеш клиент стучится на сервер 2) На сервере ClientManager принимает подключение и создает объект Client. 3) В класс клиента при этом передается объект ServerSocket, который и производит все общение с флеш клиентом. Все. Клиент создан, и помещен в карту ClientMap<String, Client> // строчный ключ равен ID клиента, он всегда уникален. Его знает и флеш клиент и сервер. Внутри класса Client есть метод, который занимается мониторингом всех входящих сообщений и парсингом протобафа (его использовал как протокол общения). Клиент получает сообщение, обрабатывает его, и шлет событие ClientEvent event = new ClientEvent(ClientEvent.MESSAGE, this); event.setMessage(message); dispatchEvent(event); Работают так же как во флеше. Если при получении события где-нибудь, например в комнате, в которой находится клиент дернуть метод preventDefault(), то флеш клиентам, подключенным к комнате, это сообщение не разошлется. Если нет, то, соответственно, оно будет отправлено всем клиентам в комнате (с указание ID клиента, который отправил сообщение). У сообщения есть так же свойство scope. По умолчанию это пустая строка. Если в это свойство добавить, например id конкретной комнаты, то сообщение будет распространено только среди клиентов этой комнаты. Если нет, то оно будет разослано во все комнаты, к которым подключен клиент. Список клиентов так же есть локальный для каждой комнаты. При добавлении клиента в комнату, ему автоматически добавляются слушатели событий DISCONNECTED, LEAVE и еще некоторых. Поэтому при прохождении какого-то из событий, локальный список клиентов автоматически корректируется Последний раз редактировалось caseyryan; 15.10.2013 в 08:23. |
|
|||||
|
Регистрация: Jan 2011
Сообщений: 200
|
Цитата:
|
![]() |
![]() |
Часовой пояс GMT +4, время: 01:42. |
|
|
« Предыдущая тема | Следующая тема » |
|
|