Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    Unsolved Remote Objects: Can't register Clients to Registry using a TCP-connection

    General and Desktop
    remoteobjects tcp network qtremoteobject remoteobject
    4
    4
    301
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      STheVoid last edited by STheVoid

      So lately I have been trying out the functionalities of the Qt remoteobjects and wanted to establish a TCP connection between a Host Node and Client Nodes using a Registry for the Clients to register at the Host Node.
      I therefore used the code provided in the official external schemas documentation: https://doc.qt.io/qt-5/qtremoteobjects-external-schemas.html and additionally enabled the remoting of the host node on the server side while I wanted to aquire the Replica object on the client side.
      My Server Side Code:

          FileManager fileManager;
      
          const QUrl registryUrl = QUrl(QStringLiteral("tcp://serverIpAdressHere:65212"));
          const QUrl extUrl = QUrl(QStringLiteral("exttcp://serverIpAdressHere:65213"));
      
          QTcpServer tcpServer;
          tcpServer.listen(QHostAddress(extUrl.host()), extUrl.port());
      
          QRemoteObjectRegistryHost registry(registryUrl);
      
          QRemoteObjectHost srcNode(extUrl, registryUrl, 
      QRemoteObjectHost::AllowExternalRegistration);
          srcNode.enableRemoting(&fileManager);
      
      //Do work with fileManager
      

      My Client Side Code:

          const QUrl registryUrl = QUrl(QStringLiteral("tcp://serverIpAdressHere:65212"));
      
          QRemoteObjectNode repNode(registryUrl);
      
          QRemoteObjectNode::RemoteObjectSchemaHandler setupTcp = [&repNode](QUrl url) -> void {
              QTcpSocket *socket = new QTcpSocket(&repNode);
              QObject::connect(socket, &QTcpSocket::connected,
                      [socket, &repNode]() -> void {
                  qDebug() << "Added client side connection";
                  repNode.addClientSideConnection(socket);
              });
              QObject::connect(socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::error),
                      [socket](QAbstractSocket::SocketError) -> void {
                  qDebug() << "Deleted socket";
                  delete socket;
              });
              qDebug() << "Connected to host with URL: " << url.host() <<":" << url.port();
              socket->connectToHost(url.host(), url.port());
          };
      
          repNode.registerExternalSchema(QStringLiteral("exttcp"), setupTcp);
      
         QSharedPointer<QRemoteObjectReplica> ptr;
         ptr.reset(repNode.acquire<FileManagerReplica>());
         Client client(ptr);
      
      //Do work with client
      

      I created a .rep file for my FileManager class which simply sends some signals with file contents to the Client and wanted to connect each Client process to the corresponding Registry using the registryUrl.

      Now my problem is that the TCP-connection seems to be established normally since the server side code approves a correct connection of the client to the provided QTcpServer (QTcpServer::newConnection() gets emitted), however the Client doesn't receive any of the file contents being provided to him using remoteobjects. Please note that the communication between the processes works fine with URLs using the local schema and therefore not using TCP. So the problem must appear in the actual registration of the clients to the registry using external schemas.
      Does anyone see a problem with my code? Can't really figure out the problem since the way the TCP connection is established is the same as described in the documentation.

      Thank you very much!

      1 Reply Last reply Reply Quote 1
      • L
        ligabre last edited by

        Hello,

        I am having the exact same issue. Did you manage to find out what was the issue?

        1 Reply Last reply Reply Quote 1
        • P
          pracedru last edited by

          I also have this problem.
          Does one need to add something for external tcp listining?

          1 Reply Last reply Reply Quote 0
          • piseprashanth
            piseprashanth last edited by

            Basically you missed to add addHostSideConnection on server side. Here is below code snippet.

            // server side
            void onNewServerConnection()
            {
            qDebug() << "onNewServerConnection";
            bool newConn = false;
            if(auto tcpServer = qobject_cast<QTcpServer*>(sender()))
            {
            while(tcpServer->hasPendingConnections())
            {
            newConn = true;
            m_pHost->addHostSideConnection(tcpServer->nextPendingConnection());
            }
            }
            }
            // Use standard tcp url for the registry
            const QUrl registryUrl = QUrl(QStringLiteral("tcp://127.0.0.1:65212"));
            // Use "exttcp" for the "external" interface
            const QUrl extUrl = QUrl(QStringLiteral("exttcp://127.0.0.1:65213"));

                // Create the server and listen outside of QtRO
                // QTcpServer tcpServer;
                auto tcpServer = new QTcpServer(this);
                auto host = extUrl.host();
            	   // We only know how to handle tcp:// and local:
                  bool res = false;
                res = tcpServer->listen(QHostAddress(extUrl.host()), extUrl.port());
                if(res)
                {
                  // m_servers.insert(url, server);
                  connect(tcpServer, &QTcpServer::newConnection, this, &YourClass::onNewServerConnection);
                }
                else
                {
                  qWarning().nospace() << "server could not listen on URL: " << extUrl.toString() << ". Error type: " << tcpServer->serverError() << ", message: " << tcpServer->errorString();
                  delete tcpServer;
                }
            
                // We need a registry for everyone to connect to
                QRemoteObjectRegistryHost registry(registryUrl);
            
                // Finally, we create our host node and register "exttcp" as our schema.
                // We need the AllowExternalRegistration parameter to prevent the node from
                // setting a hostUrlInvalid error.
                m_pHost = new QRemoteObjectHost(extUrl, registryUrl, QRemoteObjectHost::AllowExternalRegistration);
                
            
                // From now on, when we call enableRemoting() from this node, the registry
                // will be updated to show the Source object at extUrl.
            

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            OnClient side
            // Use standard tcp url for the registry
            const QUrl registryUrl = QUrl(QStringLiteral("tcp://127.0.0.1:65212"));

                // This time create the node connected to the registry
                QRemoteObjectNode repNode(registryUrl);
            
                // Create the RemoteObjectSchemaHandler callback
                QRemoteObjectNode::RemoteObjectSchemaHandler setupTcp = [&repNode](QUrl url) -> void {
                    QTcpSocket *socket = new QTcpSocket(&repNode);
                    connect(socket, &QTcpSocket::connected,
                            [socket, &repNode]() {
                                qDebug() << "Added client side connection";
                        repNode.addClientSideConnection(socket);
                    });
                    connect(socket, &QSslSocket::errorOccurred,
                            [socket](QAbstractSocket::SocketError error) {
                            
                        qDebug() << "Deleted socket";
                        delete socket;
                    });
                
                    qDebug() << "Connected to host with URL: " << url.host() <<":" << url.port();
                    socket->connectToHost(url.host(), url.port());
                };
            
                // Once we call registerExternalSchema, the above method will be called
                // whenever the registry sees an object we are interested in on "exttcp"
                repNode.registerExternalSchema(QStringLiteral("exttcp"), setupTcp);
            
            
                // local replica 
                // QRemoteObjectNode repNode; // create remote object node
                // m_pHost = new QRemoteObjectHost(QUrl(ss.str().c_str()));
                // repNode.connectToNode(QUrl(ss.str().c_str())); //QUrl(QStringLiteral("local:replica")));
            
                auto ptr = repNode.acquireDynamic("something");
            

            Prashant

            1 Reply Last reply Reply Quote 0
            • First post
              Last post