センサー
Sensorsの例では、UDPソケットを使用してprotobufメッセージを送信することで、2つのアプリケーションがどのように通信できるかを示しています。
Sensors のサンプルは以下のコンポーネントで構成されています:
protobuf_sensors
qt_add_protobuf呼び出しを使用して protobuf スキーマから生成するライブラリ。protobuf_sensor_emulator
単純なセンサーの動作をエミュレートするアプリケーションprotobuf_sensors_client
UDP ソケットからのセンサーデータを表示するアプリケーション。
クライアントアプリケーションはlocalhost
UDP ポート65500
にバインドし、エミュレータアプリケーションからのデータを待ちます。
エミュレータアプリケーションを使用してセンサーデータの値を変更し、クライアントの UDP ポートにデータを送信します。
アプリケーションはprotobuf_sensors
ライブラリから生成されたメッセージを使用して通信します。ライブラリは .proto ファイルに記述された protobuf スキーマから生成されます。
qt_add_protobuf(protobuf_sensors PROTO_FILES sensors.proto tlv.proto )
最初のファイルには Type-Length-Value メッセージが記述されており、センサーデータをラップしている:
package qt.examples.sensors.tlv; enum MessageType { Coordinates = 0; Temperature = 1; WarningNotification = 2; } // Protobuf messages imply inline data size. message TlvMessage { MessageType type = 1; bytes value = 2; }
2 番目の .proto ファイルにはセンサーメッセージの記述がある:
package qt.examples.sensors; message Coordinates { double longitude = 1; double latitude = 2; double altitude = 3; } message Temperature { enum Unit { Farenheit = 0; Celsius = 1; } sint32 value = 1; Unit units = 2; } message WarningNotification { string text = 1; }
メッセージはQProtobufSerializer を使ってシリアライズされる:
class SensorClient : public QObject { Q_OBJECT ... private: QUdpSocket m_client; QProtobufSerializer m_serializer; };
そしてエミュレータ:
class SensorEmulator : public QObject { Q_OBJECT ... QUdpSocket m_socket; QProtobufSerializer m_serializer; };
エミュレータ:エミュレータアプリケーションでSend ボタンをクリックすると、QLineEdit フィールドのデータが文字列フォーマットからメッセージフィールド固有のフォーマットに変換されます:
QObject::connect(ui->sendCoordinates, &QPushButton::clicked, this, [this]() { qt::examples::sensors::Coordinates coord; coord.setLatitude(ui->latitudeValue->text().toDouble()); coord.setLongitude(ui->longitudeValue->text().toDouble()); coord.setAltitude(ui->altitudeValue->text().toDouble()); emit coordinatesUpdated(coord); });
次に、すべてのフィールドを含むメッセージがシリアライズされ、Type-Length-Value メッセージでラップされる:
Q_ASSERT(serializer != nullptr); tlv::TlvMessage msg; msg.setType(type); msg.setValue(data); return msg.serialize(serializer);
クライアントは受信したデータグラムに対して逆の処理を行う。まず Type-Length-Value メッセージがデータグラムデータからデシリアライズされる:
const auto datagram = m_client.receiveDatagram(); qt::examples::sensors::tlv::TlvMessage msg; msg.deserialize(&m_serializer, datagram.data()); if (m_serializer.lastError() != QAbstractProtobufSerializer::Error::None) { qWarning().nospace() << "Unable to deserialize datagram (" << qToUnderlying(m_serializer.lastError()) << ")" << m_serializer.lastErrorString(); continue; }
次に Type-Length-Value メッセージが sensor メッセージにデシリアライズされる:
qt::examples::sensors::Coordinates coord; coord.deserialize(&m_serializer, msg.value()); emit coordinatesUpdated(coord); break;
最後に、Type-Length-Value メッセージが変換され、ユーザに表示される:
ui->latitudeValue->setText(QString::number(coord.latitude(), 'f', 7)); ui->longitudeValue->setText(QString::number(coord.longitude(), 'f', 7)); ui->altitudeValue->setText(QString::number(coord.altitude(), 'f', 7));
Note: サンプルを実行する前に、オペレーティングシステムが UDP ポート65500
のバインディングと UDP でのデータ送信を許可していることを確認してください。
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。