![]() |
|
![]() ![]() ![]() |
|
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
У меня есть сервер и клиент реализованные на синхронных операциях.
Все запросы клиента обрабатываются последовательно на сервере. Если клиент посылает запрос, то ответ с сервера приходит именно на этот запрос. Поток на отправку сообщений один. Поэтому несколько клиентов тоже будут обрабатываться последовательно. Но тут возникла необходимость переехать на QT-ые объекты QTcpServer и QTcpSocket. Сразу возникла проблема синхронных вызовов методов сокета. 1. Использование потоковых объектов (QDataStream, QTextStream, ...) внося большую задержку при отправке данных. Похоже это связано с буферизацией. Ее можно отключить ? 2. Не получается после операции записи синхронно висеть на чтении для получения данных. Не помогает waitForReadyRead. На нем постоянно висяк. Данные приходят лишь на слот readyRead, но тогда не получается добиться синхронности. 3. Ну и самая сложная часть. Это все работало пока была схема запрос клиента — ответ сервера. Но еще понадобилось инициатором запроса быть самому серверу. Но эти операции можно сделать не синхронными. То есть на запрос сервера ответ может быть, а может и не быть. Как тогда можно реализовать двухстороннюю схему запросов, при которой клиен выполняет синхронные запросы, а сервер асинхронные ? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
надеюсь, тебе самому понятно, что главная проблема в протоколе?
При отправке запросов клиент добавляет в очередь определенную метку, которая указывает, что за запрос был отправлен. Когда клиент получает ответ, то сверяет с текущей меткой. Если совпадает, значит это ответ на синхронный запрос, если нет, значит асинхронный ответ сервера или сбой передачи данных (определяется уже по данным сервера). |
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
То есть, например, при запросе формируется некий объект, который знает ID запроса и имеет объект ожидания. Он кладется в очередь. При получении ответа проверяется очередь запросов. Результат сохраняется в найденом объекте и сбрасывается объект ожидания. Вызывающий поток тогда может ждать да объекте, который нахожится в очереди и получать результат. Тогда вроде будет синхроннвй вызов. Я правильно понимаю ? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
xbarmaglot, ну про объект ожидания я ничего не говорил. Так как все ГУИ по определению асинхронные, поэтому ждать не стоит. Очередь только указывает на какой запрос пришел текущий ответ от сервера.
|
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
ну это я предложил вариант решения у меня нет GUI. А если не ждать, то как принимать решение на запрос?
ну там можно хранить интерфейс, который нужно дернуть при получении ответа. Или, например, слот нужного объекта. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
выполнять операции при срабатывании слота |
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
для этого существует таймер.
Хотя, я так понял, у тебя сервер всегда отвечает. Если не ответил - проблема связи. В этом случае должен дернуться другой слот. |
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
отправил запрос и положил в очередь. отправил еще запрос и положил опять в очередь ... пришел ответ сервера, взял первый запрос из очереди, проверил, подходит ли он тебе? Подходит, значит это ответ на него, извлек этот запрос из очереди и обработал ответ. Пришел ответ сервер, взял первый запрос из очереди - не подходит, значит это инициатива сервера, - обработал... |
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
||||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
xbarmaglot, и что? Если они не совпадают с первым в очереди запросом от клиента, то проблем не будет. А если будут, то это уже на совести разработчика протокола, так как нехрен делать запросы от сервера совпадающими с ответами на запросы от клиента.
|
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
bsa, что-то я уже запутался.
Что я хочу получить: 1. Есть оъект, который отвечает за отсылку и прием сообщений. Пусть это поток, который читает очередь сообщений, которые нужно отправить. И поток, который получает сообщений от сервера. Допустим протокол позволяет понят что за сообщение пришло от сервера - ответ или запрос. 2. Есть объекты, которые посылают сообщения серверу и ждут результата выполнения. 3. Есть объекты, которые ждут запроса от сервера и отвечают на них. Как все эти объекты можно связать ? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 24 Всего: 196 |
правило №1: никто никого не ждет
потоки на отправку и прием не нужны. Так как это все делается через eventLoop самого Qt. У тебя есть объект соединения с сервером. У него есть метод отправки сообщений серверу (параметры: сообщение и указатель на объект отправитель). Он добавляет в очередь сообщение с указателем на отправителя и отправляет сообщение серверу... Еще у этого объекта есть список (QMap или QHashMap, точнее) асинхронных запросов сервера с указателями на объекты, их обрабатывающие (в случае, если один тип запросов обрабатывается только одним объектом; если нужно всем отправлять - то достаточно сделать слот). Так вот, приходит от сервера что-то, оно проверяется на соответствие первому в очереди запросу, если соответствует, то запрос удаляется из очереди и вызывается определенный метод объекта-отправителя запроса. Если не совпадает, то обработчик ищется в списке асинхронных запросов. Все объекты, которые ждут ответа, ждать его не должны. Они отправили запрос и завершили работу. Продолжение работы будет после получения ответа в методе, который будет вызван в этом случае. |
|||
|
||||
xbarmaglot |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 149 Регистрация: 28.8.2012 Репутация: нет Всего: нет |
bsa, а что если не использовать очередь, а подписать всех отправителей на сигнал.
Только тогда отправитель нолжен при срабатываении слота проверить - ему ли ответ или нет. Или все-таки лучше через интерфейсы и очередь? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |