LINUX.ORG.RU

DataModel over TCP/IP

 qnetworkdatamodel,


2

3

Последние несколько недель наслаждаюсь Model/View framework из состава Qt.

Там есть все: и доступ к sql-базам данных, и просто создние своих model, и QDataWidgetMapper (позволяет легко создать свой виджет для удобного редактирования конкретного элемента модели), и QProxyModel + QSortFilterProxyModel (позволяют фильтровать данные для view не меняя данных в основной модели), и QSelectionItemModel (позволяет «расшарить» выбор элементов между View). Все круто. Определенно стоит создать цикл статей, который бы подробно описывал использование этого мощного интсрумента, хотя и в официальной документации вопрос раскрыт на должном уровне.

Но тред не совсем об этом. Во всей этой куче приятностей явно не хватает одной очень важной вещи.

Я говорю о QNetworkDataModel и QNetworkView. Можете не искать документацию об этих классах - их не существует. Но они могли бы существовать и выполнять возможность «проброса» данных из модели по сети (TCP/IP). Такие классы помогли бы упростить создание трехзвенных клиентов для баз данных, принесли бы пользу и в других сетевых приложениях, которые используют сеть для передачи данных.

Собственно вопрос. Наверняка не мне первому пришла в голову мысль, что такие классы необходимы, но мне не удалось отыскать в яндексе каких-либо упоминаний о таких проектах. В треде приветствуются ссылки на подобные проекты, описание личного опыта при использовании таких классов. Ну и ваши нужно/ненужно тоже давайте, куда уж без них.

★★★★★

Последнее исправление: trex6 (всего исправлений: 3)

Я особо не вижу смысла в этих моделях.
Так как модель должна быть представлена на 2 сторонах, а вот использование qt в качестве сервера немного ограничивает и не оправдывает себя. Если это будет не так, то стандартных моделей более чем достаточно.

zJes ★★
()
Ответ на: комментарий от zJes

использование qt в качестве сервера немного ограничивает

Раскроете вашу мысль более подробно?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Я имел в виду через. Через TCP/IP.

Как это правильно написать на английском?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

through

Именно его и имел в виду, но ошибся с написанием.

trex6 ★★★★★
() автор топика

Давайте честно, Qt это говно. Хотя-бы потому что нет нормальной системы отслеживания ошибок.
Может быть там есть соглашение о кодах возврата и кодах ошибок, которое можно использовать для единообразной и логичной отработки отказов?
Или там есть эксепшены, которые позволяют сделать ленивую обработку ошибок, каскадирование и разворот стэка?
Или там все объекты автоматные и не позволяют выполнять методы вне конкретных и чётко описанных состояний, а также имеют четкую систему отслеживания состояний и распространения ошибки?
Подождите, там есть классная штука! При ошибках в ран-тайм на консоль высыпаются сообщения об ошибках! Вот это я понимаю, технология!
И ещё, у объектов есть куча методов типа isReadable,isWritable,isЧтоТоable. Типа хочешь записать - проверь можно-ли, если нельзя - можешь выполнить код, который отработает такую ситуацию, к примеру выведет в консоль сообщение «типа ошибка».
А чего только стоят сигналы, которые в случае присоединения слота по BlockingConnection являются синхронными функциями, в случае QueedConnection отложенными асинхронными
(Хотя у них хорошо получилось организовать реактивность ModelViewFramework с помощью этих самых сигналов) ?
И как следствие жуткая помесь side-эффектов, порождаемых разными участками кода. Вот этот участок кода меняет конфигурацию создаваемого объекта, и будет выполнен в конструкторе в функции main, а вот этот участок вызывается в слоте и будет выполнен только в момент работы EventLoop. Вот этот метод мы делаем обычным синхронным методом, вот этот будет реализован в виде слота, а вот это у нас виртуальная функция-обработчик события, которая будет вызываться из EventLoop когда мы запостим своё сообщение через PostEvent.
Ребята вместо того чтобы разрабатывать логичные и понятные примитивы, из которых можно как из кирпичиков строить своё приложение, а также логичное и понятное центральное ядро - попытались предоставить функционал для решения «типичных», как им казалось задач. Вот к примеру, реализовали они у себя «конечные автоматы», а для чего? Эти автоматы малопригодны для чего-либо кроме как для решения тех проблем, которые появились у них при создании интерфейса со сложной автоматной логикой. Почему они не реализовали, к примеру что-то типа boost::program_options, которую сегодня на хабре(не к ночи будь упомянут) нахваливали, а сделали только куцый парсер конфиг-файлов в виде QSettings?
Пытались прыгнуть выше чем библиотечка для построения GUI? Как-то не вышло. И всякие попытки сделать на ней что-то, отличное от стандартного desktop-gui будут напоминать упорное жевание кактуса и кучу магии.

dmitryalexeeff
()
Последнее исправление: dmitryalexeeff (всего исправлений: 1)
Ответ на: комментарий от dmitryalexeeff

куцый парсер конфиг-файлов в виде QSettings

Отлично справляется со своими задачами. Если вам необходимо что-то больше - пишите или используйте готовое. Никто вам не запрещает.

Давайте честно, Qt это говно.

Мы учтем ваше мнение.

А чего только стоят сигналы, которые в случае присоединения слота по BlockingConnection являются синхронными функциями, в случае QueedConnection отложенными асинхронными

Это отличное решение, если _уметь_ им пользоваться.

нет нормальной системы отслеживания ошибок.

У меня нормально получается отслеживать ошибки. Какая конкретно ситуация у вас сложилась, что вы не смогли этого сделать?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6


У меня нормально получается отслеживать ошибки


ЗдОрово! Подскажите как?!
Ситуации то мы, дай бог, разрулим. Меня интересует общая стратегия.
Неа, ну я конечно понимаю что они рекомедуют стратегию:
- почитать мануал про объект, узнать когда и как можно вызывать функцию
- вызвать все isXXX у объекта,удостоверившись чтобы он был точно в том состоянии, в котором функция гарантировано вернёт результат
- вызвать функцию
- вызвать waitXXX, если функция не дай бог асинхронная (о чём не забыть прочитать в документации, где где-то между строк это будет указано )
- проверить результат и коды ошибок, для определения корректности читать документацию и исходники

Но как-то слишком замудрёно получается. Вам не кажется?

dmitryalexeeff
()
Ответ на: комментарий от dmitryalexeeff

читать документацию

Именно. Не совсем понимаю, о каких сотнях isXXX вы говорите. Приведите конкретный пример функции, для вызова которой необходимо осуществить большое количество проверок.

trex6 ★★★★★
() автор топика
Последнее исправление: trex6 (всего исправлений: 1)
Ответ на: комментарий от dmitryalexeeff

Пытались прыгнуть выше чем библиотечка для построения GUI? Как-то не вышло

Что не вышло, например, в QtNetwork и QtSql ?

x905 ★★★★★
()
Ответ на: комментарий от dmitryalexeeff

Вы заявили, что зачастую для вызова какой-то функции необходимо вызвать кучу isXXX.

Вы можете свои слова подкрепить *конкретным* примером (желательно 2-3 примера) или нет?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

А Вы заявили что отлично обрабатываете ошибки в Qt, причём раньше чем своё заявление сделал я. Так что в первую очередь жду от вас ответа, а то вдруг я не прав.

dmitryalexeeff
()
Последнее исправление: dmitryalexeeff (всего исправлений: 1)

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

Также, отсутствует соглашение о том как вообще передавать данные по сети в общем случае, т.е. нет какого-то протокола или языка, как это сделано для SQL баз данных, поэтому лично мне нужность каких-то стандартных моделей для проброса данных по сети кажется сомнительной.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Обрыв TCP-соединения.
Удаление с диска читаемого файла.
Alter Table в СУБД в то время как таблица загружена в Qt.

Дальше сами можете придумать.

dmitryalexeeff
()
Ответ на: комментарий от dmitryalexeeff

Вы заявили что отлично обрабатываете ошибки в Qt, причём раньше чем своё заявление сделал я

Читаем ваше первое сообщение в теме

И ещё, у объектов есть куча методов типа isReadable,isWritable,isЧтоТоable. Типа хочешь записать - проверь можно-ли

Так что сейчас вы откровенно лжете, что наталкивает меня на мысль, что лгали и во всех остальных сообщениях.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от no-such-file

Также, отсутствует соглашение о том как вообще передавать данные по сети в общем случае

Использование QVariant решает эту проблему.

Если вы имели в виду какой-то более-менее стандартный способ проброса данных через сеть

Я имел в виду не какие-то сферические данные в вакууме, а данных из конкретной модели, спецификация которой (индексы-описатели полей) доступны клиенту и серверу на этапе компиляции.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от htower_

Сначала он показался мне простым неосилятором, но потом я посмотрел его игнор-лист и все понял.

trex6 ★★★★★
() автор топика

Идея неплохая, но на Qt просто нормально работающий многопоточный tcp-сервер сделать не так просто, не говоря уже об одновременном использовании одной модели по сети множеством клиентов с высокой стабильностью и приемлемой производительностью.

Такие вещи лучше делать на boost::asio, а еще лучше на эрланге.

unfo ★★★★★
()
Ответ на: комментарий от dmitryalexeeff

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

Dendy ★★★★★
()
Ответ на: комментарий от unfo

Мы сейчас подумали, что уже несколько раз решали похожие задачи, и наличие обобщенного MVC via network в Qt сильно упростил бы жизнь. Сетевую часть однозначно надо делать на boost, в Qt сетка совсем говно.

Будет свободное время, попробую написать, ТС, спасибо за идею. Только нужно продумать несколько концептуальных моментов, в идеале конечно хотелось бы иметь возможность любую QAbstractItemModel распространять через сеть, наверное идеальным вариантом со стороны сервера будет создавать объект прокси-модели (QNetworkProxyModel), к которой подключается клиент (QNetworkDataModel), они уже сами синхронизируют данные между собой, клиенту даже не надо загружать все данные до их востребования.

А смысла в QNetworkView имхо вообще никакого, с чего бы отображалке затачиваться под эту в общем-то обобщенную модель?

staseg ★★★★★
()

ну опиши на qtproject зареквесть как фичу, помоги с реализацией и будет тебе счастье, а на лоре мы только поулюлююкаем и пальцами потычем

Thero ★★★★★
()
Последнее исправление: Thero (всего исправлений: 1)
Ответ на: комментарий от Thero

Я с tiago в #qt пообщался сегодня сутра. Он сказал - нафиг нужно. Сейчас планирую просто реализовать это все и дать всем попользоваться. Если народу понравится - буду двигаться в сторону апстрима.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от staseg

Мы сейчас подумали, что уже несколько раз решали похожие задачи, и наличие обобщенного MVC via network в Qt сильно упростил бы жизнь.

Рад слышать, а то у меня начало складываться впечатление, что это только мне одному может быть интересно.

QNetworkView это как раз и есть то, что ты назвал QNetworkProxyModel. Но сейчас я уже скорее склоняюсь к взаимодействию через "обезличенный" QIODevice. Прикручивать boost к Qt пока что не вижу смысла. Только если действительно буду упираться в производительность сети в своих задачах.

trex6 ★★★★★
() автор топика
Последнее исправление: trex6 (всего исправлений: 2)
Ответ на: комментарий от staseg

Сетевую часть однозначно надо делать на boost, в Qt сетка совсем говно.

как «непользователь» boost - что там сделано лучше ? (пара слов)

x905 ★★★★★
()
Ответ на: комментарий от x905

Главное - оно не тормозит. А по API концепция похожая, в бусте регистрируешь хэндлеры для обработки событий (коннект, ввод, вывод и т.д.), в Qt создаешь соответствующии слоты и подключаешь их к сигналам QIODevice. При использовании синхронного I/O разницы так и вообще нет.

staseg ★★★★★
()
Ответ на: комментарий от x905

У меня нет тестов, но на работе уже многократно проявлялись проблемы, что канал занят на четверть, а проц на всю катушку. Даже банальное

for(;;)
 socket.send(...);

у нас тормозит, хотя в бусте или POSIX напротив, канал забит, а проц на 99% в sleep. Может, Qt загибается на выбросах сигналов или еще что, я не профилировал. А может и руки или карма.

Конечно во многих случаях это может быть некритично, но в данном имхо еще как важно.

staseg ★★★★★
()
Ответ на: комментарий от staseg

у нас тормозит

Если по потоку на сокет, а данных много, то оно и сегфолтиться иногда может, стек вызовов при этом показывает различные глубины Qt.

unfo ★★★★★
()
Ответ на: комментарий от dmitryalexeeff

Ja ne vojuju, i uj virtualov tem bolee ne derju. V kachestve primerenija, ne smotria na to, chto ssoroy daje i ne pahlo, predlagajy sigrat' parteechku v shahmati.

Ok?

trex6 ★★★★★
() автор топика
Ответ на: комментарий от Thero

Rano s golimi idejami kuda-to lezt'. Vot posle togo, kak vse budet gotovo - mojno budet eshe raz poprobovat'.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

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

zJes ★★
()
Ответ на: комментарий от zJes

Если сериализовать и пулять структурировано, предварительно заворачивая в читабельный XML, через QTextStream в иодевайс?

Suigintou ★★★★★
()
Ответ на: комментарий от Suigintou

Ну это как раз тот случай, что не нужно, ибо это выродится в простое QTableView.setModel(unserializeToQAbstractItemModel(data)).
Киллер фичи как компонента не вижу. Унифицированный хелпер обмена данными клиент-сервер, тут да.
Хотя... это мое ИМХО конечно. Возможно просто туплю и не понимаю поставленной задачи.

zJes ★★
()
Ответ на: комментарий от staseg

for(;;) socket.send(...); у нас тормозит

writeData имеет код возврата, поэтому возможно неправильное использование qt, делать при этом выводы не корректно )

x905 ★★★★★
()
Ответ на: комментарий от x905

writeData имеет код возврата, поэтому возможно неправильное использование qt, делать при этом выводы не корректно )

writeData — protected аж в IODevice, кто из нас его неправильно использует? Или предлагаешь наследоваться от сокета, чтобы «правильно» отправлять им данные? На самом деле я не помнил имени функции, сейчас посмотрел, там не send, а writeDatagram. Жор ядра на 100%, забита треть стомегабитного канала. Нет, я конечно могу взять i7, распараллелить и таки забить сетку, но какой ценой? Выше еще говорят, что при таком раскладе qt иногда может упасть внутрях.

Заметь, writeDatagram — это простейшая «низкоуровневая» функция отправки UDP-пакетов. А я делал на Qt и полноценные TCP и HTTP сервера, по официальным мануалам, с обработкой событий через слоты, т.е. все как положено — оно ОЧЕНЬ тормозит. До смешного доходит, игрушечные сервера на CL работают на порядок или два быстрее.

В общем-то до поры, до времени, мне было насрать на скорость сети в Qt. Но когда обнаружилось, что наши клиенты не могут подключиться к серверам, если на них уже работает десяток человек (обмен данными довольно интенсивный), пришлось быстро что-то решать и решением оказался буст-азио.

staseg ★★★★★
()
Последнее исправление: staseg (всего исправлений: 1)
Ответ на: комментарий от zJes

если использовать стандартный иодевайс, отпадает возможность прозрачно делать серверную часть на других яп

Матчасть подучите. Никакая возможность тут не отпадает.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от staseg

Если заведете проект - кинте ссылку на код.

trex6 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.