質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.11%

MQTTを使用した際のデータのシリアライズについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,123
退会済みユーザー

退会済みユーザー

いつもお世話になります。

複数の機器間で多対多で通信を行うシステムの通信プロコルについて、どのようなものがいいのか思案しています。

 機器構成について

具体的な機器構成および環境は以下の通りです。

  • 機器間はイーサネットで接続される
  • 機器は複数あり、各々の機器同士で通信を行う
  • 機器構成内に、通信を監視するサーバ的なものが1つ存在する
  • 機器のスペックは機器により異なり、低いものはメモリの制約上C言語で組込む必要がある

これらを考慮して、通信プロトコルにはMQTTを採用しようと考えています。
プロトコルはそれでいいとして、肝心の送受信するデータフォーマットはどのようなものが適切なのか悩んでいます。

 送受信するデータについて

送受信するデータは、以下の通りです。

  • 送信側:自身の機器の状態が変化した際、自身の状態を送信する(Publish)
  • 受信側:送られてきた情報が自身にとって必要であれば、受信データを参照し、自身の動作意思決定に利用する(Subscribe)

自分としては、送受信するデータは、送信側でシリアライズして、受信側でデシリアライズするのがいいのかなと思っています。

 本題

上記の機器構成および送受信するデータをシリアライズ/デシリアライズする場合、MQTTのデータフォーマットは一般的にどのように実現するのでしょうか。
自分なりに調べてみたところ、ProtocolBuffersというものが探していたものに近いのかと思いました。が、C言語での構築例が検索してもあまり引っかからず、一般的ではないのかなぁと思いました。
そもそも、低スペック機器でのMQTTの使用方法が根本的に違うのでしょうか。(例えば独自プロトコルを生成し、バイナリデータでやりとりするとか)

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

こんにちは。

異言語間のシリアライズ用には下記2つが有名です。
ProtocolBuffers
MessagePack

C++用なら下記の前者2つが有名です。
boost::serialization
cereal
Theolizer(手前味噌です。失礼)

JavaやC#用はそれぞれ数種類あります。たくさんあるので省略。

でも、C言語用はみたことありません。
リフレクションもなく、テンプレートさえないC言語の標準機能で実現するには厳しすぎるせいと思います。

エンディアンの問題を回避できるようでしたら、<stdint.h>を使ってサイズを固定してmemcpy()ベースでやり取りすることも視野に入ると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/30 20:12

    ありがとうございます。
    やはり、C言語では難しいのすかね・・・。おっしゃる通り、memcpyでのやり取りも考えてみます。

    キャンセル

  • 2017/07/01 22:02

    msgpack は C で書けたと思います。

    キャンセル

0

Protocol Buffer をお選びになるなら C でなく C++ になります。
なお、C++ になるならば gRPC を使われた方が良いかもしれません。gRPC に元々キューが存在します。

また MQTT を使う前提ならば JSON で良いかと思います。RPC over MQTT として扱いたいならば JSONRPC の形式が良いと思います。ただし JSON で扱う場合、システムで使うエンティティの量が増えたり正規化したい場合などには苦しくなる可能性があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/30 20:05

    ありがとうございます。
    >JSON で扱う場合、システムで使うエンティティの量が増えたり正規化したい場合などには苦しくなる可能性があります。
    とのことですが、その理由をご教授いただくことはできますでしょうか。

    キャンセル

  • 2017/06/30 21:41

    gRPC の場合は proto ファイルという設計書の様なファイルからエンティティを出力するという方式を取ります。これにより例えばエンティティの一部の型を変更した際にビルドエラーになってくれてバグを見つける事が出来るのですが、JSON はどちらかというと各実装で作り上げられたエンティティをシリアライズして通信する事になるので、片方のエンティティのメンテが漏れたり色々な事が起きやすくなります。

    キャンセル

  • 2017/06/30 22:00

    追加のご回答ありがとうございます。
    なるほど、そういう問題があるのですね。
    納得いたしました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る