0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TurboWarpでmqtt-min.jsというMQTTカスタムブロックを実装した話

Last updated at Posted at 2025-12-10

はじめに

TurboWarp/Scratchの作品をIoTとつなぎたい時、ブラウザからMQTTを直接扱える拡張ブロックが欲しくなるのですが、既存の拡張は常時稼働している仲介サーバーが必要だったり、ブラウザのWebSocket制限に引っかかったりと気軽に使えるものが少ないと感じていました。そこで、Codex(OpenAIのコーディングアシスタント)にペアプロしてもらいながら MiniMQTT という超ミニ実装を仕上げ、mqtt-min.js として公開しました。私は仕様整理や検証に集中し、実際のコード生成や最適化はCodexに頼っています。

リポジトリ: https://github.com/ufoo68/turbowarp-custom-block
CDN URL: https://ufoo68.github.io/turbowarp-custom-block/mqtt-min.js

どんなブロックか

拡張ブロック

TurboWarpの「拡張機能を追加」から上記URLを貼ると、以下のブロックが出現します。

  • MQTTに接続 scheme://host:port/path clientId ...
  • MQTT切断 / 接続中?
  • 購読 topic ...
  • publish topic ... msg ...
  • 最後に受信したメッセージ
  • MQTTで受信したら(ハットブロック)

Codexと進めたプレーンJavaScript実装のざっくりメモ

プレーンJSでMQTTをしゃべると聞くと難しく感じますが、Codexと会話しながら次の3要素だけ押さえれば十分でした。

  • パケット生成: CONNECT/SUB/PUBなどの先頭バイトとRemaining Length、文字列の長さプリフィックスを素直に Uint8Array で組み立てるだけ。TextEncoder/Decoder を使えばUTF-8処理も完結。
  • ブラウザ接続: new WebSocket(url, ['mqtt']) でバイナリ接続し、onopen でCONNECT、setInterval でPINGを送る。binaryType='arraybuffer' にしておけば受信ハンドラはそのままバイト列として扱える。
  • Scratch連携: メッセージを受けたら runtime.startHats('minimqtt_onMessage') を呼び出すだけでハットブロックが反応。複数メッセージは _pendingMessages でキューにしておけば取りこぼしにくい。

ざっくり流れが掴めるように、Codexが生成したコードを最小限にしたスニペットを貼っておきます。

const ws = new WebSocket('wss://broker.hivemq.com:8884/mqtt', ['mqtt']);
ws.binaryType = 'arraybuffer';

ws.onopen = () => {
  ws.send(pktConnect('scratch-' + Math.random().toString(16).slice(2)));
  setInterval(() => ws.send(pktPing()), 24000);
};

ws.onmessage = (ev) => {
  const { type, payload } = parseMqtt(new Uint8Array(ev.data));
  if (type === 'publish') {
    lastMsg = new TextDecoder().decode(payload);
    runtime.startHats('minimqtt_onMessage');
  }
};

pktConnectparseMqtt は本文で紹介した Uint8Array ベースの関数をそのまま呼んでいるだけで、ライブラリに頼らなくてもMQTTの最小セットが動くことがわかると思います。

Codexがバイナリ処理の骨組みを一気に書いてくれるので、私は仕様の確認とテストに集中できました。MQTTが分からなくても、この3点さえ把握していれば最低限のクライアントを作れるはずです。

使い方

TurboWarpエディタを開き、「拡張機能を追加」から https://ufoo68.github.io/turbowarp-custom-block/mqtt-min.js を貼る。

スクリーンショット 2025-11-10 234532.png

例として HiveMQ Public Broker を使う場合は SCHEME: wss / HOST: broker.hivemq.com / PORT: 8884 / PATH: mqtt を指定して接続。

動作検証

以下のような感じでブロックを組んでみました。

スクリーンショット 2025-11-10 235633.png

  1. SCHEME: wss / HOST: broker.hivemq.com / PORT: 8884 / PATH: mqttに接続
  2. topic: scratch/mqtt/inでsubscribe
  3. メッセージを受信したらtopic: scratch/mqtt/outでメッセージを返す

簡単のためもう一方の通信クライアントは https://www.hivemq.com/demos/websocket-client を使いました。結果としてそれぞれにメッセージのやり取りができたことを確認できました。

スクリーンショット 2025-11-11 000223.png

スクリーンショット 2025-11-11 000243.png

おわりに

MQTTは仕様がコンパクトなので、Scratchの拡張としてもまだ遊べる余地があります。mqtt-min.js をぜひ環境に合わせてforkしたり、より高度な拡張を作る際のベースにしてみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?