Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обслуживание запросов пользователей (сервер), хороша ли моя идея? 
V
    Опции темы
null56
Дата 31.3.2009, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



Собственно хотел обсудить возможные варианты решения моей задачки, потому что у меня в голове только одна, которую я считаю наиболее эффективной, но может быть я ошибаюсь...
Ситуация такая:
Существует сервер, который принимает запросы от пользователей.... само сообщение имеет следующий вид: <код><текст запроса>.... по выполнению должен прийти соотвествующий ответ...
Чего я вижу в этой ситуации:
1) Отделяем код из текста сообщения
2) Проверяем наличие данного кода в массиве (ну или хеше) указателей на функции
3) В случае нахождения функции с данным индексом, вызываем ее и передаем ПРИ НЕОБХОДИМОСТИ нужный callback, для работы с СУБД.
Короче все делает вызываемый метод
Наиболее оптимального решения данной задачи я не вижу, другие у меня ассоциируются с кучей if, что само собой отбрасывает их.
Хотел бы спросить, хорошая ли моя идея или же существуют наиболее эффективные решения, если есть, будьте добры поделитесь ими пожалуйста.
Что меня привлекло в этом способе, так это быстрый поиск нужного ветвления и компактность кода....
Заранее благодарен за помощь...
PM MAIL   Вверх
Lazin
Дата 31.3.2009, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Подумай, что будет, если у тебя будет много одновременных подключений(конечно если будет)
в общем, если возможна одновременная работа множества клиентов, то нужно предусмотреть диспетчеризацию сообщений от разных клиентских сессий.
Самый простой вариант, сервер принимает одновременно только одно подключение, тогда, то что ты придумал еще может работать
вариант посложнее, сервер создает по потоку на каждую клиентскую сессию, это будет работать только при небольшом количестве одновременно работающих клиентов.
Работать это может так, клиент конектится к серверу, сервер создает для него поток, и в этом потоке принимает запрос(сообщение) от клиента, затем, в этом-же потоке синхронно выполняет запрос к БД и отправляет результат клиенту и либо разрывает соединение и завершает поток, либо ждет следующий запрос от клиента.
Самый правильный вариант - асинхронная обработка сообщений(шаблон проектирование Proactor). Сервер создает N потоков, в каждом из них он может обрабатывать какие либо события. Когда подключается очередной клиент, в одном из потоков(пула потоков) вызывается обработчик этого события, который получает ссылку на вновь созданное соединение, на основе этого соединения он создает объект ClientSession, и помещает его например в хэш таблицу, либо связывает его с соединением как нибудь еще. Далее, клиент отправляет команду(запрос) серверу, в пуле потоков сервера вызывается обработчик этого события, который получает в качестве параметра соединение и данные которые были получены от клиента, он извлекает объект класса ClientSession, соответствующий этому соединению(который может содержать какие либо данные уникальные для каждой сессии) и выполняет запрос к БД(то-же асинхронно) и завершается. Далее обработчик завершения обработки запроса к бд вызывается в пуле потоков, получает результат и отправляет его клиенту.
Такой подход позволяет не создавать по потоку на каждого клиента, к тому-же он позволяет минимизировать простои, например, пока выполняется прием данных от одного клиента, можно посылать данные другому, и тд...
PM MAIL Skype GTalk   Вверх
null56
Дата 31.3.2009, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



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

ЗЫ: реализован сервер на qt, а там будет, скорее всего, невозможно реализовать подобную модель, так как там принцип сигналов и слотов, позволяет работать с объектом и обрабатывать события от него только в том потоке, где этот объект был создан...

Так что вопрос: как наиболее быстрее и проще определить запрос от клиента ;-)
PM MAIL   Вверх
semibug
Дата 31.3.2009, 21:25 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 323
Регистрация: 27.3.2009

Репутация: нет
Всего: нет



А почему вариант с switch  (if/elsif) не устраивает?
Все таки безопаснее вызывать обработчики непосредственно, нежели через указатели на них.
Если выбор способа ( таблица обработчиков ) обусловлен скоростью работы, вряд ли это будет заметно на фоне более ресурсоемкой работы с БД (судя по описанию Вы её используете).
Для красоты можно разбить команды на группы, и, к примеру, сначала переключаться на switch по первому байту, а затем во внутреннем switch по второму. Но это уже дело вкуса.
Что касается компилятора, то скорее всего он превратит свичи в выборку из таблицы "значение-адрес", т.е. по сути проделает то, что Вы хотите сделать вручную, но скорее всего безошибочнее.

PM   Вверх
null56
Дата 1.4.2009, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 2
Всего: 12



да, вполне привлекательный способ.... 
спасибо... 
на счет управляемости ветвления по байтам, надо подумать
PM MAIL   Вверх
jonie
Дата 1.4.2009, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 15
Всего: 118



лично я бы не перил мозги себе в части писанины своего велосипеда в виде сервера и клиента... чем очереди гарантированной доставки плохи ? или системы обмена сообщениями вроде http://qpid.apache.org/ ?

Кстати, в том варианте что я привел (про qpid) можно сразу и комманды распозновать, если так можно выразится, запихивая разные из них в разные "секции".



Это сообщение отредактировал(а) jonie - 1.4.2009, 10:43


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0564 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.