Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using Capnproto with QTcpSocket



  • I am trying to use capnproto with qtcpsocket.
    I have seen the stackoverflow post regarding how to integrate the KJ event loop with Qt's event loop, but I am not really sure how to implement it, as I have only used Qt's QTcpSocket with signals and slots so far, and I have never made my own threads with my own event loops.

    I have actually managed to use capnproto with qtcpsocket, but the behaviour is kinda bad, as I am using the qtcpsocket with signals and slots, and in the slot connected to readyRead signal I just let the KJ library in capnproto use the same qtcpsocket by overriding the kj::inputstream's tryRead function, and calling the qtcpsocket's read function in the override implementation. This works mostly, but I dont always recieve all my data if the frequency of readyRead signals is high.

    My override implementation looks like this:

    class QtCapnpStream : public ::kj::InputStream , public ::kj::OutputStream  {
    public:
        explicit QtCapnpStream(QTcpSocket * inputSocket), socket_(inputSocket) {};
        inline size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override {
            size_t ret = socket_->read(static_cast<char*>(buffer), maxBytes);
            return ret;
        };
        inline void write(const void* buffer, size_t size) override {
            size_t ret = socket_->write((char*)buffer, size);
        };
    private:
        QTcpSocket * socket_;
    };
    

    In my client code I then declare this (after initializing and connecting my socket_ to a host)

        bufferedInputStreamWrapper = new ::kj::BufferedInputStreamWrapper(new QtCapnpStream(socket_);
    

    and in my slot connected to readyRead on my socket, I do this

        ::capnp::PackedMessageReader reader(*bufferedInputStreamWrapper);
    

    and I use this reader further in my slot to unpack the data I have read.

    Is the only solution to make this work an event loop integration (like in the stack post), or can I modify what I have done so far somehow?

    Or if anyone has used capnproto in Qt, could you show me a simple example how this could be implemented?



  • Hello there steinito,
    I am trying to do the same, I opened a post on the Nvidia forum about my issues, I use UDP to try but I wish to use TCP as soon as possible, maybe my post will help you but in the same time could you be kind enough to share your full qt project please ?
    I want to try your code with Isaac SDK to see if it's working and use it as a worker thread to see if it solve the high frequency issue.
    Thank you !
    Planktos



  • Hi, I cannot show my project as it is proprietary, but you can implement it exactly as I described above.
    Simplest form, just create the override in the same header to the class you have your socket, then just create a socket as you normally would, pass it into a BufferedInputStreamWrapper as I showed, and then you connect readyRead to whatever function you want to parse your data and call the ::capnp::PackedMessageReader reader(*bufferedInputStreamWrapper); in that function.

    This only works if the amount of data you are sending is small and doesn't trigger multiple readyReads, which I painfully found out the hard way. I have not yet made a KJ eventloop integration, as I don't really know how.

    I will honestly most likely abandon QTcpSocket for this project and use another socket library, like Poco where this is not an issue.


Log in to reply