Один из вариантов решения - тонкая настройка keep-alive соединений на сервере, чтобы "отстреливание" клиента происходило быстрее. TCP Keepalive HOWTO - настройка tcp keep-alive в Linux. Чтобы не менять настройки всего сервера можно использовать библиотеку libkeepalive.
$ export KEEPIDLE=1 #net.ipv4.tcp_keepalive_time $ export KEEPINTVL=1 #net.ipv4.tcp_keepalive_intvl $ export KEEPCNT=5 #net.ipv4.tcp_keepalive_probes $ LD_PRELOAD=./libkeepalive.so nc jabber.local 5222
При таких настройках интервал между keep-alive запросами будет 1 секунда и при отсутствии ответа будет предпринято 5 попыток после чего соединение будет разорвано на application layer. Чтобы видеть передачу пакетов через соединение, использовался tcpdump
sudo tcpdump -i eth0 -n -p -v host jabber.local and port 5222 ... 17:48:34.032178 IP (tos 0x0, ttl 64, id 3461, offset 0, flags [DF], proto TCP (6), length 40) client > server: Flags [.], cksum 0x37eb (incorrect -> 0xf46c), ack 1, win 913, length 0 17:48:34.032435 IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 40) server > client: Flags [.], cksum 0xe12c (correct), ack 1, win 5840, length 0 17:48:35.031257 IP (tos 0x0, ttl 64, id 3462, offset 0, flags [DF], proto TCP (6), length 40) client > server: Flags [.], cksum 0x37eb (incorrect -> 0xf46c), ack 1, win 913, length 0 17:48:35.031540 IP (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 40) server > client: Flags [.], cksum 0xe12c (correct), ack 1, win 5840, length 0 ...
Для эмуляции разрыва связи я использовал iptables
$ sudo iptables -I INPUT -p tcp -s jabber.local -j DROP
При желании настройки TCP keep-alive можно применить ко всему серверу, а не только определенному приложению. Для этого в файл /etc/sysctl.conf (или /etc/sysctl.d/keep-alive.conf) добавить
net.ipv4.tcp_keepalive_time = 1 net.ipv4.tcp_keepalive_intvl = 1 net.ipv4.tcp_keepalive_probes = 5
И применить настройки
sudo sysctl -p
Недостаток этого варианта в том, что он не гарантирует доставку сообщений, которые отправляются в промежутке между keep-alive запросами сервера. И в дополнение в сети создается служебный траффик, объемом 80B/s на каждое подключение.
Вторым вариантом стало подтверждение доставки сообщений. Для этих целей существует расширение XMPP протокола XEP-0184: Message Delivery Receipts. В случае поддержки этого расширения у обоих собеседников появляется возможность видель статус доставки а также просмотра отправленного сообщения. Если один из собеседников не поддерживает расширение, то оно отключается и у второго собеседника.
Клиенты, поддерживающие XEP-0184: Miranda, Psi+, Tkabber, Gajim и некоторые другие. К сожалению Pidgin в данный момент не поддерживает Message Receipts и похоже в ближайшее время поддерживать не будет.
Комментариев нет:
Отправить комментарий