-
Начал реализовывать задачу, в которой служба должна общаться с GUI-приложением в обоих направлениях. Т.е. GUI может посылать определенные команды службе, та их принимать. В свою очередь, в произвольные моменты служба должна отправлять GUI-приложению определенные данные (статистику). Довольно часто.
Раньше подобные задачи делал на Named Pipes. Теперь, в силу условий, нужно сделать на сокетах. С Инди TIdTCPClient, TIdTCPServer почти не работал ранее. Есть несколько глупых вопросов:
1. Насколько надежны эти компоненты? Приложение должно работать 24/7/365.
2. Как я понял, сервер принимает сообщения от клиента в IdTCPServerExecute. Я могу, путем обращения к списку активных потоков соединений получить соединение с GUI-приложением и отправить туда данные в произвольном месте программы? В каком потоке пойдут эти данные?
3. Насколько будет надежна такая двусторонняя связь в одном канале? Будут ли тормоза?
4. При приеме данных в клиенте нужно создавать отдельный поток на чтение данных или достаточно по таймеру делать read...?
5. Могут ли пакеты, отправляемые службой, склеиваться?
6. Не лучше ли в GUI и службе реализовать и клиент и сервер?
В примере чата на Инди реализовано как раз взаимодействие в одном канале. Но возникают сомнения в надежности. Данные у меня пойдут сплошным потоком, а клиент должен будет успеть сказать службе "свое слово".
Заранее спасибо за ответы!
-
> _alex__ (15.07.09 22:08)
На 1 и 2 - не знаю Indy, не работал.
3 - Связь надежна (хотя каков критерий надежности?), если надежен канал передачи данных, то же относится и к тормозам. NamedPipes при работе в сети так же используют этот же физический канал связи. 4 - Вариант с чтением по таймеру на мой взгляд "не камильфо". Насчет отдельного потока - это зависит от того в каком режиме ты работаешь. Так как ты выбрал Indy, то совет для этой библиотеки не дам. А если абстрагироваться от библиотеки и считать, что мы просто работаем с сокетом, то при блокирующем сокете (и не OVERLAPPED I/O) и при независимой по логике твоего приложения (полный дуплекс) работе каналов чтения и передачи - надо создать отдельный поток на чтение и на запись. В случае использования неблокирующих сокетов и/или перекрытого вывода вывода создавать отдельный поток для чтения нет особого смысла. 5 - Да. TCP -это просто сплошной поток, река. 6 - Нет, не вижу смысла. Если у тебя есть аргументы за - расскажи.
> В примере чата на Инди реализовано как раз взаимодействие > в одном канале. Но возникают сомнения в надежности. Данные > у меня пойдут сплошным потоком, а клиент должен будет успеть > сказать службе "свое слово".
Для тебя канал связи (в данном случае сокет) - это дуплексный канал, клиент может передавать независимо от чтения.
-
> 1. Насколько надежны эти компоненты?
Вполне себе нормальные компоненты, не хуже других в плане надежности.
> В каком потоке пойдут эти данные?
В дополнительном, а именно в том в котором вызывается метод-обработчик IdTCPServerExecute
-
Спасибо большое! Почему спросил про надежность - много читал постов, что неблокирующие TServerSocket, TClientSocket достаточно глючны. И со сложной логикой программирования. Т.к. самому не охота возиться с апи winsock, решил попробовать инди.
Еще два уточнения: 1. Если клиент вызывает метод disconnect, на сервере при этом автоматически удаляется указатель на его поток из списка потоков? Т.е., могу ли я нарваться на несуществующий поток, если клиент вдруг завершил работу (в т.ч. и аварийно)?
2. Как пакеты могут склеиваться, если пока клиент не прочитает очередную посылку сервера, последний не сможет отправить следующую. В этом же принцип синхронной передачи? Или я что-то упустил? В моем понимании, клиент будет получать от сервера по одному пакету (в моем случае, это короткая строка-команда) за одну операцию readln. Поправьте меня, если я не прав.
-
> _alex__ (16.07.09 10:45) [3]
> 2. Как пакеты могут склеиваться, если пока клиент не прочитает > очередную посылку сервера, последний не сможет отправить > следующую. В этом же принцип синхронной передачи? Или я > что-то упустил? В моем понимании, клиент будет получать > от сервера по одному пакету (в моем случае, это короткая > строка-команда) за одну операцию readln. Поправьте меня, > если я не прав.
TCP не гарантирует сохранения границы пакетов. Пакеты могут фрагментироваться, склеиваться... Восстановление границ пакетов лежит на твоем приложении или в некоторых случаях на библиотеке, которую используешь. ReadLn в Indy -возможно как раз вариант библиотеки, которая возвращает строку, ограниченную терминатором, то есть фактически восстанавливает границы пакета. Но по Indy я не спец.
-
> неблокирующие TServerSocket, TClientSocket достаточно глючны
Не более глючны чем IdTCPServer/Client
> со сложной логикой программирования
Это да, неблокирующий режим будет посложнее. Но если уж сравнивать с IdTCPServer/Client, то сравнению подлежит блокирующий режим, поскольку IdTCPServer/Client предоставляют только блокирующий режим.
> Если клиент вызывает метод disconnect, на сервере при этом > автоматически удаляется указатель на его поток из списка > потоков?
Нет.
> могу ли я нарваться на несуществующий поток
При желании можно грабли где-угодно найти)
> пока клиент не прочитает очередную посылку сервера, последний > не сможет отправить следующую
Это почему же не может ? Может, и ничто этому не мешает.
TCP - поточно-ориентированный протокол.
-
сделал тестовый пример, многое прояснилось. К примеру, то что сервер может отправить сколько угодно сообщений клиенту. Они все помещаются в очередь. А клиент потом может сколько угодно "расхлебывать" эту кучу. Все пришло в том же порядке и без склейки. А эта очередь где создается? На клиенте? Просто сервера уже нет, а сообщения все читаются
-
> К примеру, то что сервер может отправить сколько угодно > сообщений клиенту
Равно как и наоборот. После того как соединение между клиентом и сервером успешно установлено, понятия "клиент" и "сервер" перестают существовать - с этого момента существует канал инф.обмена между двумя партнерами по этому соединению, эти партнеры равноправны, каждый из них вправе как передавать партнеру, так и принимать от партнера инф.поток.
> эта очередь где создается?
Очередей на самом деле две - одна на стороне передатчика (очередь передачи), другая на стороне приемника (очередь приема).
> сервера уже нет, а сообщения все читаются
Они выбираются приемником из очереди приема. Как только та опустеет в результате "расхлебывания", очередная попытка чтения приведет к исключению.
-
Спасибо за информацию! Достаточно все прозрачно и проще, чем Pipes. Микрософт навернуло, конечно, там... Это и понятно - более высокоуровневое взаимодействие с элементами безопасности. Жалко, что все завязано на двух портах, которые, как правило, закрывают в целях безопасности.
Появятся вопросы, спрошу еще! Спасибо! :)
-
> > В каком потоке пойдут эти данные? > > > В дополнительном, а именно в том в котором вызывается метод- > обработчик IdTCPServerExecute
Что-то эксперимент показал, что данные от сервера уходят в основном потоке. Блокируешь основной поток тяжелым процессом, данные перестают уходить. Это нормально?
-
Нет, не нормально.
-
> _alex__ (16.07.2009 17:09:09) [9]
Это нормально, если тебе нужна серилиазация.
-
Скорее всего, отправлять данные от сервера буду в отдельном потоке (так и так получится). Наличие очередей у приемника и отправителя здорово упрощает задачу. Пусть сервер шлет сколько угодно и когда угодно. Клиент так же в потоке все примет и обработает. На тесте нормально все проходит.
-
Задачу ГУИ не знаю, но, как правило, это управление, конфигурирование, наблюдение за службой. Я общаюсь с ней по HTTP (суйчас так многие ус-ва конфигурируются) Что имеем: клиент есть на любой машине и его писать не надо, нас даже не волнует платформа клиента, пишем небольшую часть на сервере и все
Удачи...
ЗЫ Делал на TTcpServer...
-
> Я общаюсь с ней по HTTP (суйчас так многие ус-ва конфигурируются)
Время десктопов проходит... :) К сожалению, сильных знаний html нет. Да и вебморду надо нарисовать красивую еще суметь. GUI кроме отправления команд будет и отображать результаты работы службы.
-
> _alex__ (17.07.09 20:58) [14]
Опять повторюсь, я не знаю вашей задачи, но: 1. вебморду рисовать - это уже дело десятое. 2. > кроме отправления команд будет и отображать результаты работы > службы. не вижу тут проблем
|