Как общаться между HTML / Javascript и C ++ в Qt WebChannel независимым от платформы способом? - PullRequest
0 голосов
/ 16 мая 2018

Для настольных компьютеров (Windows, Mac, Ubuntu) есть QWebEngineView, а для мобильных устройств (Android, iOS) - нативное QWebView.

К сожалению, мобильные телефоны не поддерживают QWebEngineView.
Например, как описано в посте ниже:
Как использовать Qt WebEngine и QWebChannel?
setWebChannel() доступен в QWebEnginePage, который доступен только в QWebEngineView. Однако у QWebPage нет такого метода, который доступен в QWebView.

Теперь существует еще один независимый от платформы способ, который работает на всех платформах, как описано в Интеграция веб-контента .
Но в примере используется QWebChannelAbstractTransport, который можно использовать только с JSON. Теперь JSON, из-за его чрезмерного описания, может быть довольно дорогим, если модуль C ++ находится где-то на сервере, а HTML - локальный; то есть реальное общение клиент-сервер через Интернет.
Было бы лучше, если бы они использовали протобуф.

Существует ли какой-либо оптимизированный и независимый от платформы способ вызова HTML / Javascript из C ++ в Qt?

[Примечание: Кстати, текущий способ вызова C ++ из Javascript на Ct довольно удобен с использованием channel.objects, и я хотел бы сохранить этот способ.]

1 Ответ

0 голосов
/ 17 мая 2018

С QWebChannel для связи между C ++ и HTML / JS, в настоящее время Qt использует JSON для передачи вызова / данных события (см. QWebChannelAbstractTransport & QWebChannel.js ). В Интернете JSON по сравнению с Google Protobuf может иметь издержки при отправке имен полей, но это должно быть незначительным по сравнению с «Без оптимизации данных (строк / текста)» в обоих протоколах.

Существует ли какой-либо оптимизированный и независимый от платформы способ вызова HTML / Javascript из C ++ в Qt?

Оптимизированный способ был бы для Qt предоставлять строку / байты ( вместо QJsonObject ) в QWebChannelAbstractTransport и JS (оба конца соединения), чтобы мы могли использовать собственные протоколы для транспорта.

Обходное / альтернативное решение (возможно, не оптимизированное) будет использовать текущую абстракцию для передачи с использованием протокола Protobuf / custom, как здесь:

См. Примеры Qt WebChannel

    In websockettransport.cpp (shared folder in examples)
        C++

        void WebSocketTransport::sendMessage(const QJsonObject &message)
        // Convert message from QJsonObject to Protobuf/custom protocol and
        // use m_socket->sendTextMessage or sendBinaryMessage as required


        void WebSocketTransport::textMessageReceived(const QString &messageData)
        //with QWebSocket::binary[ or text]MessageReceived slot, 
        //convert the message from client (in Protobuf/custom protocol) to 
        //JSON and still
        emit messageReceived(message.object(), this); 

JS: Точно так же, поскольку QWebChannel.js использует сокет, необходимо установить сокет в двоичный или текстовый формат, как требуется, и преобразовать сообщение ProtoBuf / пользовательского протокола в json, как того требует Qt

.

Простая иллюстрация использования Protobuf (необходимо, чтобы все сообщения были предварительно определены) / пользовательский протокол в QWebchannel:

C ++ -> WebSocketTransport (JSON в Protobuf / пользовательский протокол) -> передача -> websocket JS (Protobuf / пользовательский протокол в JSON) -> (QWebChannel.js)

JS -> (QWebChannel.js) -> JS websocket (JSON в Protobuf / настраиваемый протокол) -> передача -> WebSocketTransport (Protobuf / настраиваемый протокол в JSON) -> C ++

Примечание: JS работает с объектами (из JSON или любого протокола) и может не нуждаться в преобразовании, как указано выше; но это нужно определить.

...