🆕 Smalruby 独自 — upstream に存在しない、Smalruby のために新規追加された機能
複数の Smalruby インスタンス間で broadcast event と グローバル変数 をリアルタイム共有する機能。子供たちが教室や家庭でネットワークを通じて連携した作品(複数人で協力するゲーム、リレー型のお絵描きなど)を作れるようにする。
旧 Mesh (v1) は外部サービス Skyway に依存していたが、v1 のサービス停止に伴い、AWS AppSync + DynamoDB をバックエンドに自社で再構築したのが Mesh v2。
- 小学生として、友達のスモウルビーと自分のスモウルビーで「メッセージを送る」「相手の変数を読む」をして、複数人で動くゲームを作りたい
- 教師として、教室全員がインターネット越しに簡単な合言葉でグループに入れて、リアルタイム通信を体験させたい
- 家庭学習中の子として、別の場所にいる家族や友達と画面を分けて協力プレイができる作品を作りたい
-
ブロックパレットの「拡張機能を追加」から Mesh を選ぶ
-
接続モーダル (
connection-modal) が開く。ホストとして新しいグループを作るか、メンバーとして既存グループ名で参加するかを選択 -
ホスト選択時:自動的にランダムグループ名(例:
【いきたにんた】)が割り当てられて登録完了 -
「エディターへ行く」でブロックパレットに戻ると、メッシュカテゴリに緑チェックが付く
-
メニューバーの「メッシュ」をクリックすると、ドメイン / グループ名 / 接続期限のカウントダウン が確認できる
メッシュカテゴリのブロックは少なく、
センサーの値で他ノードのグローバル変数を読み取るのが基本。 -
接続後、
broadcastブロックでイベント送信、グローバル変数の自動同期、mesh.sensor_value(name)で他ノードの値読み取りが可能に -
グループの最大接続時間は 35 分(
MESH_MAX_CONNECTION_TIME_SECONDS)
通信モードは環境に応じて自動選択される:
| モード | リアルタイム配信 | 環境制約 |
|---|---|---|
| WebSocket | AppSync subscription | プロキシ/フィルタが WebSocket を許可 |
| Polling | 2 秒周期の query | フォールバック(403/503 で WebSocket 不可な環境) |
URL パラメータ ?force_polling=1 でクライアント側から強制 polling 化できる。
クラスに参加中(生徒)または先生がクラス管理でクラスを選択中の場合、Mesh ドメインはそのクラスの参加コードに自動で固定される。
- 例: 参加コードが
xuzk93のクラスに参加中 → Mesh ドメインの初期値・固定値はxuzk93 - 接続モーダルのドメイン入力欄は読み取り専用になる(クラスを抜けると編集可能に戻る)
- 同じクラスの先生・生徒は自動的に同じドメインに集まるため、グループ検索・参加が容易になる
- 先生の「選択中のクラス」は Redux 上に保持される(モーダルを閉じても維持/ページリロードでクリア。先生 idToken のキャッシュ仕様と整合)
- 連動解除時の挙動: 生徒がクラスから退出 / 先生がログアウトすると、Mesh ドメインは連動前の値に戻る(連動開始時にスタッシュ)。連動前にユーザーが手動で設定したドメインや URL
?mesh=のデフォルト値が復元される
実装: packages/scratch-gui/src/lib/mesh-v2-classroom-binding.jsx
end-to-end 動作確認: tools/playwright-verify/mesh-v2-classroom-binding.mjs — 2 タブ (教師 + 生徒) を自動で操作してドメイン連動を検証する手動 E2E スクリプト。
- 拡張機能登録:
packages/scratch-gui/src/lib/libraries/extensions/index.jsx—extensionId: 'meshV2' - 接続 UI(接続モーダルの mesh-v2 専用ステップ):
packages/scratch-gui/src/components/connection-modal/mesh-v2-initial-step.jsxpackages/scratch-gui/src/components/connection-modal/mesh-v2-network-filtered-step.jsxpackages/scratch-gui/src/components/connection-modal/mesh-v2-scanning-step.jsx
- 状態管理:
packages/scratch-gui/src/reducers/mesh-v2.js - Ruby 連携:
packages/scratch-gui/src/lib/ruby-generator/mesh_v2.js— Ruby コード → mesh ブロック変換packages/scratch-gui/src/lib/ruby-to-blocks-converter/mesh_v2.js— mesh ブロック → Ruby コード
packages/scratch-vm/src/extensions/scratch3_mesh_v2/:
| ファイル | 責務 |
|---|---|
index.js |
scratch 拡張ブロック定義、UI 連携 |
mesh-service.js |
ファサード。各 manager mixin を集約 |
mesh-client.js |
Apollo Client、GraphQL endpoint URL |
gql-operations.js |
GraphQL queries / mutations / subscription 定義 |
network-filter.js |
エラー分類、503 検出、testWebSocket |
periodic-sync.js |
WebSocket モード時の 15 秒 fallback (fetchAllNodesData) |
polling-client.js |
Polling モードの 2 秒周期 (pollEvents / POLL_GROUP_DATA) |
subscription-manager.js |
WebSocket subscription 受信 |
heartbeat-manager.js |
host/member heartbeat と接続タイマー |
data-sender.js |
グローバル変数送信 (REPORT_DATA) |
broadcast-receiver.js |
受信した event を順序保証して Scratch broadcast に流す |
event-sender.js |
fireEvent キューイング + バッチ送信 + orderKey 生成 |
group-lifecycle.js |
createDomain / createGroup / joinGroup / leaveGroup |
rate-limiter.js |
sendData の rate limit + マージ |
utils.js, name-search-utils.js |
URL パラメータ、グループ名検索 |
サーバー側実装。詳細は専用ドキュメントを参照:
infra/smalruby-mesh-v2/docs/architecture.md— システムアーキテクチャ、データフロー、テーブル設計infra/smalruby-mesh-v2/docs/api-reference.md— GraphQL スキーマ完全リファレンスinfra/smalruby-mesh-v2/docs/deployment.md— デプロイ手順infra/smalruby-mesh-v2/docs/development.md— 開発ガイドinfra/smalruby-mesh-v2/docs/operations.md— モニタリング・コスト・スケーリング
Mesh 拡張機能のブロックは「メッセージ送信」「他ノードの変数読み取り」が中心:
| ブロック ID | 説明 |
|---|---|
meshV2_broadcast |
名前付きイベントを送信 |
meshV2_broadcastAndWait |
イベント送信して受信側の処理完了を待つ |
meshV2_whenIReceive |
イベント受信時の Hat ブロック |
meshV2_getSensorValue |
他ノードのグローバル変数を読み取り |
各ブロックの詳細仕様は
docs/smalruby-language-spec-extensions.ja.mdを参照。
MESH_GRAPHQL_ENDPOINT— AppSync GraphQL エンドポイントMESH_API_KEY— API キーMESH_AWS_REGION— リージョン (ap-northeast-1)
meshV2:domain— ユーザー固有のドメイン名(CRC32 ハッシュベース)
?force_polling=1— Polling モード強制?mesh_debug=1— mesh 通信のデバッグログを表示
詳細試算は cost.md を参照。AppSync + DynamoDB の per-operation 単価と production 設定での月額試算を網羅。
mesh は最重要機能のため、関連コードを変更したときは必ず Playwright によるデグレ確認 を実施する。手順は .claude/rules/scratch-gui/mesh.md の「デグレ確認手順」を参照(heartbeat TTL の関係で 5 分以内に完了させること)。
# 単体テスト
bin/dx bash -c "cd packages/scratch-vm && npm exec tap -- test/unit/mesh_service_v2*.js"
# integration test
bin/dx bash -c "cd packages/scratch-vm && npm exec jest test/integration/extensions/mesh-v2-*.test.js"cost.md— AWS コスト試算docs/extension-mesh-v2/— 拡張機能としての観点 (準備中、本ページとの分担は要検討).claude/rules/scratch-gui/mesh.md— クライアント側開発ルール、デグレ確認手順.claude/rules/infra/smalruby-mesh-v2.md— サーバー側開発ルール
- 旧 Mesh (v1) → v2 移行: 複数の関連 Issue
- Issue #554 (pollGroupData 統合) — PR #564
- Issue #555 (プロトコルロギング) — PR #557
- Issue #556 (orderKey によるイベント順序保証) — PR #563
- Issue #566 (mesh-service.js 責務分割) — PR #569
- Issue #592 (Skyway 停止対応によるバックパック自動マイグレーション)




