Почему отваливаются вебсокеты workerman с приложением на ionic. Кто виноват клиент или сервер?
Всем привет.
Есть вебсокеты на workerman к ним подключается приложение на ionic из под андроида например.
Когда сворачиваем приложение - через некоторое время рвется соединение с сервером. В основном это происходит при длительном простое приложения в свернутом режиме, либо при временном отключении связи на телефоне к примеру.
Причем соединение рвется странно, сервер думает по-прежнему, что клиент подключен, клиент тоже не видит, что сокет закрылся, но сообщения по сокету не ходят. Сделали функцию ping для приложения, если нет отклика - оно переподключается к серверу. На сервере при этом счетчик активных соединений растет. Таким образом получается, что сокеты закрываются, но приложение и сервер этого не видят. Кто виновен в данной ситуации клиент или сервер? Куда копать или как можно потестить?
Сталкивался с таким поведением и на iOS.
Ваше решение с пингом верно в данном случае. Можно дополнить двунаправленным. По сути отмечать на стороне сервера когда была последняя активность клиента (ведь если клиент постоянно шлет ПИНГ, то активность должна быть), если клиент пропустил 2-3 тайма для пинга - отрубать сокет (тут можно нежно: послать пинг от сервера и если нет ответа рубить; или жестко: сразу рубить)
Так что поле для фантазий.)
ЗЫ. когда вы включите мобильную связь и пойдете по улице у вас еще IP меняться начнет и так же разрывы сокет-соединения будут.
Заметил, что если со стороны сервера слать в сокет любое сообщение с периодичностью 5-10 секунд, то клиент при этом закрывает соединение корректно в случае обрыва связи. Т.е. теперь на сервере нет незакрытых соединений.
Теперь осталось разобраться почему в фоновом режиме приложение на телефоне не хочет работать с сокетами. Может проблема заключаться в том, что оно написано на ionic и если бы оно было нативным, то было бы лучше?
VladimirDronik, в части разработки на мобилках - могу только сделать предположения.
Сокет соединение подразумевает постоянную сетевую активность. моб устройства стараются экономить заряд и трафик - так что скорее всего отключение вы не победите, или в противном случаи ваш софт будет сажать аккумулятор. Полагая именно по этой причине и придумали PUSH )
В проекте в котором я участвовал на стороне разработки сервера, коллеги на клиенте решили проблему таким образом:
1) держим сокет сколько можем
2) на стороне сервера ведется контроль (авторизация+сокет) - если пользователь авторизовался (login) и явно не посылал команды "выход" (logout) и произошло соединение = такой пользователь считается активным до тех пор пока не пришлет команду "выход" (logout)
3) сокет до пользователя контролируется сервером, если клиент не ответил - сокет убивается (со стороны сервера) и клиенту ставиться флаг "в сети без сокета"
Если произошло событие о котором надлежит уведомить пользователя и пользователь в "вошел" (login)
1) есть активный сокет - шлем данные на сокет
2) стоит флаг"в сети без сокета" - шлем "пинок" через ПУШ
Суть "пинка" - разбудить девайс, что бы тот создал сокет.