multi-tier architecture: how to have out-of-process signal-slot?
-
Hello everyone,
I am very new to Qt development: actually I am trying to understand features and pro-con.
I have experience in developing apps for the Windows OS using COM (ActiveX).
I developed in the past one multi-tier application that is made of several SW modules (modular approach) running most of them in their own process.
With COM mechanism I was able to create SW modules (EXE) raising events and other SW modules (EXE) receiving events also if they were running in different processes: the COM engine was creating automatically proxy-stubs to handle events and also methods invocations through the process boundaries. It was very easy.
Now I am looking at Qt and I cannot find something similar.
The signal-slot mechanism is wonderfull but can only work in the same process.
One can use D-bus but only on *nix OSes (so not a general solution).
Other RPC protocols (SOAP or REST) need some configuration for every event or method to be used remotely (and I have some concerns about performances).
I googled to find something but I was not lucky.
This example (http://www.ics.com/blog/multilayered-architecture-qt-quick) is not really what I mean for multilayer architecture: the QML base GUI is running in the same process of the Qt C++ created object.
I am really surprised about this and I am asking you all where I am missing.Let's say that you want to create a 2-tier application.
One application would be developed using Qt C++ making some kind of business logic: receiving maybe commands (method invocations) and raising events on command completion.
Then I would have the GUI layer. Let's say I would have two different application for GUI: one with QML and one with QWidgets.
The 2 GUI apps would be in their own process (EXE). And also the business logic app would be in a separate process (EXE).
Well, I would like to press a button in one of the GUI apps and having a method called in the business logic app (so in a different process).
Then I would like to raise an event in the business logic app and have it being received by the GUI apps (that are in different processes).In many parts of the Qt documentation I can find that keeping separate presentation and business logic have many benefits, but I cannot find how to get it in a real multi tier architecture!
Any suggestion for me aboutt where to start reading something about this matter?
Thank you in advance to all of you and have a nice day.Best regards
Alberto
-
Hi and welcome to devnet,
signals/slots mechanism is not a IPC system; it work only inside the same executable.
In my company we have a 2-tier application:
- 1 server executable
- 1 GUI executable (can be deployed and executed on several machines)
the communication between these component are made using standard TCP sockets. We use Google Protobuf to define the messages format.
Everything is done asynchronously; I mean
- The user clicks on a Button
- The GUI sends a TCP message to the server and don't wait for the answer
- The server handle the request and when new data are ready sends it to the GUI
- The GUI receives the new data and update the interface
-
Hi and welcome to devnet,
One Qt module that might be of interest is the QtRemoteObjects
Hope it helps
-
Hello,
QxOrm library provides QxService module to exchange data between processes (and over network).
There is a tutorial here : http://www.qxorm.com/qxorm_en/tutorial_2.html
And QxEntityEditor can generate all source code (definition of entities you want to transfer + services layer for basic operations like get a element, update or delete it, you can of course add and implement your own service).With QxOrm and QxEntityEditor, you don't have to deal with serialization and network stuffs, all is managed by the library.
-
Hello,
thank you mcosta (or maybe I should say 'grazie' as likely you are italian like me)
thank you SGaist
thank you qxormI would like to comment on your answers.
Yes, I understood that there is not an IPC system for remoting signal/slot mechanism.
@mcosta: you wrote that you are using standard TCP sockets and Google Protobuf.
This can be a solution, but it requires you to manage TCP connections on your own and to add some sort of encoding/decoding of messages (if I understood correctly with protobuf you must edit some sort of declarative description of the interface).
I would like to have a simpler way!@sgaist: thank you for the link. I had a look. it seems a very young project (late 2014) though sponsored by Ford Motor Company (and maybe supported by KDAB).
The idea is very similar to what I am looking for.
The approach maybe it is not the one I would have chosen: it seems to me that it aims to create a remote copy (the RemoteObject) of the complete object state.
It seems to me that they are trying to transfer across the process boundary not only signals and slots (that can be considered the public interface of the object) but the entire object.
Does it make sense? Will it perform well in case of a lot of remoted objects?@qxorm: the solution of your company seems to be dedicated to data exchanging between processes and not to signals and slots. Maybe it can be adapted. For sure it is an important part of a multi tier distributed application, but I would like to focus on an easy way for exchanging signals and slots between processes.
I continued googling to find something and I found something.
I found something that was available in the early days of Qt (at least before Qt 5): QtopiaIpcAdaptor.
It seems that it was part of the Qt 4 libraries and that then it was discontinued.
It was then maintained as Qt Extended and Qt Extended Improved: but it seems that this two projects were never moved to Qt 5.
The idea behind it seems to me the one I will vote for.There is a messaging system the makes the interprocess communications.
There is a very simple and transparent use of the remoting of signals and slots.
You can rely on Qt serialization for known types and you must provide your custom serialization for user defined types.
You can decide to publish single signals or all signals.
If you inherit from QtopiaIpcAdaptor class you get all this behaviour in your derived class.So, my final question is:
how can it be possible that Digia doesn't provide a mechanism for remoting signals and slots as a part of the Qt libraries?
I think it is absolutely necessary if you want to make some sort of multi-tier applications (and I don't think that a multi-tier application running in same process is a real multi-tier application).
They had one (QtopiaIpcAdaptor), they had also QCop (discontinued), they have QDbus (only for Linux systems and it requires declarative description of the interfaces).
A mechanism for having inter-process events and functions invocations was available in MS VB6 (COM based) before 2000.I am looking at Qt for developing commercial applications in the field of industrial automation: it looks very very interesting.
I would like to have a GUI using QML. I would like to have a backend in Qt C++ running in a different process. But I would like a simple way to connect them!
And I would like an official supported solution: there are a lot of open source projects that start but never reach a production state.
Commercial license for Qt development is not very cheap (the MS one is cheaper): I think and I hope they can do something more for remoting signals and slots.I add some notes based on my recent googling:
- message system based on 0MQ (it looks it is a very powerful, reliable, flexible and fast inter-process message system). There are some attempts to use it in Qt, but nothing official
- signal/slot remoting mechanism using introspection and native serialization for know types, simple way to provide custom serialization for custom types
Then you can have a good basis (IMHO) for developing multi tier applications that can run on one PC or even distributed (by only changing the connection parameters).
It is a long reply: sorry. But I would like to share with someone else my doubts about Qt.
Have a nice day
Alberto
-
@IngAU said:
This can be a solution, but it requires you to manage TCP connections on your own and to add some sort of encoding/decoding of messages
If you don't care about persistent connections you can use UDP socket (simpler to use).
Protobuf allows to declare the interface (a sort of IDL). So you don't need to encode/decode the contents: it creates a C++ class with standard get_ and set_ methods for each field.A mechanism for having inter-process events and functions invocations was available in MS VB6 (COM based) before 2000.
yes but is Windows only and (IIRC) is only per-host.
There's no cross-operating system version of it.I think and I hope they can do something more for remoting signals and slots.
You can ask them as a Feature request but is not possible to implement something in a general cross-platform way.
-
You also have QxtRpcService that might be of interest.
On a side note DBus is not linux only anymore, both Windows and OS X can use it.
-
@IngAU As you can see you can use different solutions to achieve your goal but every solution has is how features and limitations (QxtRpcService needs you manage the Socket, DBus is limited to processes running on the same machine and so on).
This is why Qt doesn't offer a single solution.For large-scale/High-performance solutions you could also use some DDS solution like OpenDDS, RTI Connext, and so on