Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Архитектура системы обмена сообщениями

4.9K
21 февраля 2009 года
efferson
57 / / 08.12.2005
Друзья, архиважный вопрос smile

Есть клиент/сервер - имитация службы обмена сообщениями аля ICQ. Клиент умеет подсоединяться к серверу (при этом для каждого клиента на сервере создаётся трэд), отсылать ему команды и получать ответы на эти команды. Однако, требуется, что бы сервер мог и по своей собственной инициативе отправлять клиенту сообщения.

Вот тут вот и возникает проблема: как сделать так, что бы клиент мог параллельно:
1. отправлять команды / принимать ответы на них
2. получать сообщения от сервера

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

Есть тривиальное решение - сделать получение сообщений от сервера ещё одной командой клиента, а на сервере складывать сообщения в коллекцию или БД. Но будет ли это тру? smile

Кто-нибудь может подсказать, как поступить в данной ситуации?
1.9K
21 февраля 2009 года
andriano
474 / / 10.01.2008
А кто мешает открыть еще один сокет?
4.9K
22 февраля 2009 года
efferson
57 / / 08.12.2005
На другом порту? По моему это будет идейно не правильно :)
1.9K
22 февраля 2009 года
GreenRiver
451 / / 20.07.2008
Цитата: efferson
На другом порту? По моему это будет идейно не правильно :)



Почему же? Тут в принципе два варианта: либо спрашивать время от времени сервер, нет ли новых сообщений (что по-моему как раз и не есть тру), либо открыть порт на прослушивание и не париться... По-моему это самое простое решение...

502
22 февраля 2009 года
Jail
550 / / 30.01.2007
Цитата: GreenRiver
... По-моему это самое простое решение...


как сказать. я бы брал и смело юзал RPC. реализация просто и в тоже время эффективна.
http://ru.wikipedia.org/wiki/Remote_Procedure_Call

4.9K
23 февраля 2009 года
efferson
57 / / 08.12.2005
Ну для обращений от клиента к серверу используется как раз XML-RPC :)

А на счёт второго сокета... судя по всему это действительно единственный вариант, при котором не придётся изобретать костыли...

Однако, тут тоже есть один скользкий момент. При каждом подключении придётся определять тип сокета - сокет для команд или сокет для сообщений.

С учётом моей предметной области это будет примерно так, как изображено на приатаченных диаграммах (uml там естественно не валидный - рисовал что бы отобразить суть идеи) :)
241
26 февраля 2009 года
Sanila_san
1.6K / / 07.06.2005
А зачем гоордить два сокета, когда на клиенте можно постоянно прослушивать один, а по мере нужды отправлять через него команды с клиента? А в клиенте соорудить какой-нибудь разборщик, который и будет различать сообщения, приходящие от сервера.
4.9K
26 февраля 2009 года
efferson
57 / / 08.12.2005
Рассматривал этот вариант, однако, отказался от него по следующим причинам:

1. Запрос_комманды/получение_ответа суть операция атомарная. Поэтому классическая схема прокси, принимающей сообщение от сервера и передающей их тому или инному процессу, не применима, т.к. в этом случае придётся разделить процесс отправки запроса и получения результата (что неприемлимо).
Есть вариант организовывать надстройку над сокетом, инкапсулирующую в себе логику разделения данных, и обращаться к ней из обоих процессов как к обычному сокету. Однако, тут придётся организовывать буфер, т.к. возможна ситуация, когда информация придёт для одного процесса, а к надстройке обратиться другой. Надстройке придётся считать данные и положить их в буфер, пока к ней не обратиться нужный процесс. Вобщем имеем потенциальный источник ошибок.

2. На стороне сервера так же придётся контролировать одновременный доступ к сокету только одного процесса, т.к. возможен вариант, когда клиент запросит список пользователей, а другой отправит ему сообщение, ибо на сколько я помню матчасть - при записи одним процессом сокет не блокируется на запись другими
5
27 февраля 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: efferson
Рассматривал этот вариант, однако, отказался от него по следующим причинам


Концепция следующая.
С каждой стороны (код в принципе один и тот же) сокет обслуживают два потока управления: для записи и для чтения данных. Команды могут посылаться как с одной так и с другой стороны.

Отправка команды сводится к формированию объекта, представляющего команду и обработчику результата выполнения. Этот обработчик будет вызваться при получении отчета о выполнении команды на принимающей стороне, эти обработчики могут выполняться как в отдельном потоке управления, так и в потоке чтения из сокета. Все команды последовательно нумеруются, ответы принимающей стороны в своем заголовке содержат соответствующий номер команды, таким образом команда и обработчик ответа у нас связаны.

Процедура выполнения команды на принимающей стороне может происходить в отдельном потоке управления с очередью принятых команд. После выполнения команды отправляем отчет с результатами назад. В случае серверной части этот поток может быть один на несколько клиентов (зависит от сложности выполнения команд).

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог