qtqt5qtremoteobjects

What's different QRemoteObjectRegistryHost and QRemoteObjectHost?


I am new to learn QRemoteObjects, i understand usage of Direct Connection with a Dynamic Replica.But i don't understand Connections to Remote Nodes using a Registry mechanism.I got confused the relationship between QRemoteObjectRegistryHost, QRemoteObjectHost, QRemoteObjectNode and QRemoteObjectReplica, can anyone give me simple explanation?

In Registry method
server use code like this

regNode = QRemoteObjectRegistryHost(QUrl('local:registry'))
srcNode = QRemoteObjectHost(QUrl('local:replica'), QUrl('local:registry'))
#is there will create two Local Socket  server?

client use

repNode = QRemoteObjectNode(QUrl('local:registry'))

What's the difference QUrl('local:registry') and QUrl('local:replica')?
And I think QRemoteObjectHost(QUrl('local:replica'), QUrl('local:registry')) is redundant in this method.


Solution

  • In the example you provide the advantage is not observed and therefore you see it redundant.

    In some applications there is a need to have several sources and it would be redundant for the replicas to have to connect to each source, so the task of QRemoteObjectRegistryHost is to have a connection point for several sources and that the replicas are connected through it.

    For example, the following scheme shows its use:

     ┌-------------------┐                ┌-------------------┐
     | QRemoteObjectHost |                | QRemoteObjectHost |
     └--------┬----------┘                └-------┬-----------┘
              |                                   |
              |                                   |
         ┌----┴-----------------------------------┴----┐ 
         |          QRemoteObjectRegistryHost          |
         └--┬-------------------┬-----------------┬----┘
            |                   |                 |
            |                   |                 |
    ┌-------┴----- ---┐ ┌-------┴---------┐ ┌-----┴------- ---┐
    |QRemoteObjectNode| |QRemoteObjectNode| |QRemoteObjectNode|
    └-----------------┘ └-----------------┘ └-----------------┘
    

    Multiple nodes can be registered through QRemoteObjectHost, and the QRemoteObjectHost is registered in the QRemoteObjectRegistryHost so that any QRemoteObjectNode can obtain replicas of the QRemoteObjectHost nodes through QRemoteObjectRegistryHost.

    To illustrate the functionality I created the following example:

    ├── register.py
    ├── replica.py
    └── source.py
    

    register.py

    from PyQt5 import QtCore, QtRemoteObjects
    
    
    if __name__ == "__main__":
        import sys
    
        app = QtCore.QCoreApplication(sys.argv)
    
        regNode = QtRemoteObjects.QRemoteObjectRegistryHost(
            QtCore.QUrl("tcp://127.0.0.1:5557")
        )
    
        sys.exit(app.exec_())
    

    replica.py

    from functools import partial
    import sys
    
    from PyQt5 import QtCore, QtRemoteObjects
    
    
    if __name__ == "__main__":
    
        app = QtCore.QCoreApplication(sys.argv)
    
        node = QtRemoteObjects.QRemoteObjectNode(QtCore.QUrl("tcp://127.0.0.1:5557"))
    
        replicas = []
    
        def on_remoteObjectAdded(info):
            name, url = info
            print("object added", name, url)
            replica = node.acquireDynamic(name)
    
            wrapper = partial(on_initialized, replica, name)
            replica.initialized.connect(wrapper)
            replicas.append(replica)
    
        node.registry().remoteObjectAdded.connect(on_remoteObjectAdded)
    
        def on_initialized(replica, name):
            wrapper = partial(print, name)
            replica.dataChanged.connect(wrapper)
    
        sys.exit(app.exec_())
    

    source.py

    import sys
    
    from PyQt5 import QtCore, QtRemoteObjects
    
    
    class Node(QtCore.QObject):
        dataChanged = QtCore.pyqtSignal(str)
    
    
    if __name__ == "__main__":
    
        app = QtCore.QCoreApplication(sys.argv)
    
        parser = QtCore.QCommandLineParser()
        parser.addPositionalArgument("url", "Host URL different to tcp://127.0.0.1:5557")
        parser.addPositionalArgument("name", "Name of node")
        parser.process(app)
        args = parser.positionalArguments()
    
        if len(args) != 2:
            print("only url and name is required")
            sys.exit(-1)
    
        url, name = args
    
        if QtCore.QUrl("tcp://127.0.0.1:5557") == QtCore.QUrl(url):
            print("url different tcp://127.0.0.1:5557")
            sys.exit(-1)
    
        node = Node()
        srcNode = QtRemoteObjects.QRemoteObjectHost(
            QtCore.QUrl(url), QtCore.QUrl("tcp://127.0.0.1:5557")
        )
        srcNode.enableRemoting(node, name)
    
        def on_timeout():
            data = QtCore.QDateTime.currentDateTime().toString()
            node.dataChanged.emit(data)
    
        timer = QtCore.QTimer(interval=1000, timeout=on_timeout)
        timer.start()
    
        sys.exit(app.exec_())
    

    Then run the following commands on different CMDs/terminals:

    python register.py
    
    python replica.py
    
    python source.py tcp://127.0.0.1:5558 node1
    
    python source.py tcp://127.0.0.1:5559 node2
    

    And in the CMD/terminal console of replica.py you will see the following:

    # ...
    node1 Tue Jan 7 22:32:09 2020
    node2 Tue Jan 7 22:32:09 2020
    node1 Tue Jan 7 22:32:10 2020
    node2 Tue Jan 7 22:32:10 2020
    # ...