Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизКак бы реализовали архитектуру клиента? Найти похожие ветки
← →
wl © (2012-08-07 19:30) [0]Клиент-серверное приложение через сокеты, по некоторому протоколу (отправляем сообщение - получаем квитанцию).
Иногда сервер присылает сообщения, иногда клиент отсылает, по наступлению какого-нибудь события (большинство через очередь, но некоторые нужно отправлять немедленно, ну к примеру пинг, или что батарейка сейчас сядет).
Пытаюсь сделать так: основной поток приложения собирает события в очередь, или пытается отправить немедленное событие.
Дополнительный поток ждет команды от сервера, если ничего нет, и очередь не пуста, разгружает очередь на сервер.
Чувствую, что получается криво:
1) событие отправки немедленной команды иногда попадает на момент передачи данных второго потока (скажем, передается большой файл, а мы ему команду пинга в середину). Но это можно избежать, отложив или отменив немедленную команду (мне оба варианта не нравятся).
2) второй поток может сработать на получение квитанции на немедленную команду (во время ожидания команды от сервера), и тогда основной поток её не получает.
да, язык неполная реализация posix c (для кроссплатформенности), ничего асинхронного, типа boost::asio, нет. приходится с потоками извращаться...
← →
Dimka Maslov © (2012-08-07 19:48) [1]Сервер работает в одном потоке, при получении сообщения от клиента он порождает новый поток, который и работает в дальнейшем с данным клиентом. При этом уже становится не важно, что в это время делают другие потоки и не надо разделять команды на медленные и немедленные. И всё это желательно делать в службе, дабы в случае чего она самоперезапускалась.
← →
wl © (2012-08-07 20:08) [2]сервер и так в отдельных потоках с клиентами работает.
проблема в том, что медленные команды нужны, так как они могут накапливаться в очереди на диске, когда соединения нет (допустим, клиент на мобиле, и едет в метро. или очередь не разгрузилась, а клиент вырубился без питания, после включения через день немедленные события в очереди также не нужны, как потерявшие актуальность), после появления соединения, очередь потихоньку разгружается, и при появлении немедленного события желательно его быстро выгрузить в перерывах между "транзакциями" передачи сообщений из очереди.
Простите за неполное описание, одно из условий - качества связи практически постоянно недостаточно для того, чтобы в очереди не было сотни-другой событий.
← →
tesseract © (2012-08-07 20:17) [3]Один сокет на клиента + id соединения + раскидывание по callback процедурам? Выходит типо эмулятор асинхронности.
← →
asail © (2012-08-07 20:18) [4]Можно срочные сообщения подпихивать в начало очереди обычных.
← →
asail © (2012-08-07 20:22) [5]А можно по два потока на обоих сторонах для каждого соеденения и 2 соккета - один для общей очереди, другой для срочных сообщений. А сервер пусть уж разруливает, что первее...
← →
wl © (2012-08-07 20:40) [6]
> tesseract © (07.08.12 20:17) [3]
сервер вероятнее всего изменить не удастся, приходится работать с тем что есть. но на всякий случай можете подробнее объяснить? для чего id соединения, если клиенты его разрывают в любой момент? Впрочем каждый клиент уникален, присылает свой id при подключении к серверу. при сбое соединения поток для клиента на сервере убивается, при следующем подключении сервер клиента "узнает", и опять начинается обмен сообщениями. У сервера для каждого клиента есть своя очередь сообщений (для этого в дополнительном потоке я жду от него команд).
> asail © (07.08.12 20:18) [4]
это как-то сложно получается. я сделал так, что пока квитанция от сервера не придет, сообщение из очереди не удаляется, если в начало накапливать мгновенные, то есть 3 неприятные ситуации
1) надо знать, на какое медленное сообщение пришла квитанция, оно уже не в начале очереди, скипать все мгновенные?
2) в очередь могут попасть несколько мгновенных одинаковых сообщений (скажем медленное сообщение обрабатывалось 1 минуту, а за это время набежало еще 5 мгновенных, которые каждые 10 секунду генерировались), актуальное - возможно, последнее, что их фильтровать?
3) если приложение было отключено, и эти мгновенные сообщения потеряли актуальность при следующем запуске, что с ними делать? удалять, отправлять последнее по времени, сортировать по приоритетам?
в общем, это ведет к чрезмерному увеличению ответственности класса очереди, переусложнению дизайна этого класса,и багам, багам, багам
← →
wl © (2012-08-07 20:50) [7]
> asail © (07.08.12 20:22) [5]
ух какая мысль интересная! а сервер не загнётся? Если клиентов будет тысяч десять?
надо всё обдумать
← →
wl © (2012-08-07 21:01) [8]а может использовать некую мини-очередь из мгновенных сообщений, которые будут иметь приоритет перед обычной, и на диск сохранятся не будут? при дублировании мгновенного события удаляется предыдущее, отправкой и приемом занимается один поток, не мешая основному заниматься сбором данных
← →
wl © (2012-08-07 21:30) [9]не получится, дополнительный поток же блокируется на операции чтения из сокета, придется делать либо неблокирующий сокет (и тогда второй поток будет вертеться непрерывно, расходуя батарею), либо прерывать ожидание чтения из сокета по таймауту, опять же пропуская отправку мгновенных сообщений.
пойду покурю доки по мультредам, может достигну просветления
← →
MsGuns © (2012-08-07 21:47) [10]Стесняюсь спросить, а какова начальная задача ?
НАдеюсь, не телефонный справочник и не крестики-нолики по сетке ?
← →
tesseract © (2012-08-07 22:02) [11]
> для чего id соединения, если клиенты его разрывают в любой
> момент?
Как раз для таймаута разрыва. Типа печенек - правда должен быть сборщик из убивающий по таймауту.
← →
tesseract © (2012-08-07 22:04) [12]
> У сервера для каждого клиента есть своя очередь сообщений
> (для этого в дополнительном потоке я жду от него команд).
>
В posix нет сообщений - только callback - или уже что-то дорисовали?
← →
wl © (2012-08-07 22:07) [13]типичное приложение - антивор. программа при подключения телефона к сети, либо выгружает очередь совершённых звонков, смс, смены симок. либо, если есть соединение с сетью, и, к примеру, изменились координаты, немедленно сообщить об этом на сервер. я понимаю, что gps можно и в очереди хранить, чтобы видеть полную картину перемещения, но это не моё требование, и не мне, как исполнителю, переубеждать заказчика. задача поставлена - будь добр сделай
← →
wl © (2012-08-07 22:11) [14]
> tesseract © (07.08.12 22:04) [12]
не, это что-то на уровне приложения - допустим клиент долго в оффлайне, и сервер потавил себе в очередь событий передать на клиента при включении - запрос куда звонили в последнее время, куда перемещались в последнее время. как только клиент появится, его сначала запросят про первое, потом про второе.
наверное "сообщение" это неверный термин - "команда", "операция" более правильно
← →
tesseract © (2012-08-07 22:17) [15]Не ну это уже очередь и скорее всего запросов! Не путай понятия - а то вообще сам запутаешься. В callback реализуешь запросы - ставишь нужные процедуры запросов в очередь и по событию подключения рисуешь - пул потоков или очередь команд - это офигенно сложный шаблон - лучше сверься с литературой. Там многие камни уже освящены. С сообщениями там проще в разы. Но свою очередь рисовать - аццкий гемор.
← →
Dennis I. Komarov © (2012-08-07 22:19) [16]Что-то я не понял, велосипед? Или шпиона пишем?
← →
xayam © (2012-08-07 22:22) [17]
> А можно по два потока на обоих сторонах для каждого соеденения
> и 2 соккета - один для общей очереди, другой для срочных
> сообщений
можно и с одной очередью. Дополнительный параметр при создании события - приоритет.
Очередь сортировать/выполнять по приоритету: срочно/обычно/когда свободен
← →
wl © (2012-08-07 22:47) [18]
> Dennis I. Komarov © (07.08.12 22:19) [16]
с удовольствием бы посмотрел на готовое решение, в плане поучиться. И нет, это не что-то незаконнное. по крайней мере впереди предстоит сертификация ФАПСИ. но не суть. до неё как до луны.
> xayam © (07.08.12 22:22) [17]
а как прерывать блокирование сокета, ожидающего приема данных с сервера? делать неблокирующим, тогда бесконечный цикл проверки, есть ли данные в сокете, живой ли сокет, вообще убьет батарею.
Вероятно совет {asail © (07.08.12 20:18) [4]} пока самый подходящий, еще бы продавить его через заказчика
← →
Dennis I. Komarov © (2012-08-07 23:29) [19]
> с удовольствием бы посмотрел на готовое решение, в плане
> поучиться.
На сколько знаю, операторы предлагают подобные услуги в B2B секторе... или я не понял смыслу задачи...
← →
tesseract © (2012-08-07 23:43) [20]
> а как прерывать блокирование сокета, ожидающего приема данных
> с сервера? делать неблокирующим, тогда бесконечный цикл
> проверки, есть ли данные в сокете, живой ли сокет, вообще
> убьет батарею.
> Вероятно совет {asail © (07.08.12 20:18) [4]} пока самый
> подходящий, еще бы продавить его через заказчика
В posix НЕТ неблокирующих сокетов. Там идёт Thread on connect шаблон. Если нужен приоритет - делай две очереди или два разных callback.
← →
wl © (2012-08-08 00:05) [21]
> tesseract © (07.08.12 23:43) [20]
а такая система не на всех посикс-системах работает?
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
ну или на крайний случай select(....) с нулевым таймаутом
← →
tesseract © (2012-08-08 08:57) [22]
> wl © (08.08.12 00:05) [21]
На MacOS / Freebsd - отработает нормально. Но ИМХО всё рано проще с блокирующими в потоке.
← →
wl © (2012-09-07 22:58) [23]опять подниму свою тему, ситуация с потоками осложняется тем, что соединение должны быть по SSL. если использовать открытую библиотеку OpenSSL, то наталкиваюсь на ограничение - к одному SSL-connection нельзя обращаться из разных потоков. У GnuTLS, судя по описанию, та же проблема.
Библиотека является thread-safe, bla-bla-bla, за исключением доступа к соединению из разных потоков.
голову себе сломал уже, пытаясь разрулить проблему, но простого решения найти не могу, костыли чтоль строить? так ведь сломаются рано или поздно.
А казалось бы такая задача простейшая, сто раз реализованная, а толком инфы найти не удается
← →
KSergey © (2012-09-11 08:52) [24]Если бы вы потрудились сесть, изложить кратко и понятно что хочется получить (а не ваши фантазии на тему "я сделал так - не получается", это не интересно), то и вам бы стало понятнее что же на самом деле надо, и возможно идей по архитектуре было бы больше.
Но вы идете верной проверенной дорогой каши во всем, которая кончается известно чем. Успехов!
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.075 c