エミュレーター
エミュレーターは、システムが通信する API、デバイス、サービスを Signal Lab が演じるものです。1 つのアドレスで待ち受け、ルールに従って応答します。HTTP API はルートで、OSC・UDP・TCP デバイスは「これが来たら、これを返す」というルールで応答し、MQTT ブローカーは通常のブローカーとして動作したうえで独自のルールでも応答します。遅くなったり、失敗したり、ときどきダウンしたりできるので、依存先の調子が悪いときにシステムがどう振る舞うかをテストできます。すべてのやり取りは集計・一覧表示され、インスペクターに送られます。
エミュレーターは 1 つのドキュメントです。エミュレーター 画面はそのライブラリを管理します。同じドキュメントが、実験の中では エミュレーター ノードとして、コマンドラインでは signallab emulate で、さらに API や MCP からも実行され、どこでも同じように応答します。
画面
左側はライブラリ (ライブラリ) です。すべてのエミュレーターがプロトコルとアドレスとともに表示され、実行中のものには点滅する点とリクエスト数が付きます。右側には選択したエミュレーターの設定とルールがあり、その下に受信したもの (ライブ) が表示されます。
エミュレーターを作る
ライブラリの上部にあるボタンのいずれかを押します。
ボタン 作成されるもの 待ち受けアドレス そのまま動作するルール 1 つ + HTTP API HTTP API 127.0.0.1:18080GET /health→ 200{"status":"ok"}+ OSC デバイス OSC デバイス 127.0.0.1:9100/ping→ 回数を int で付けた/pong+ UDP デバイス UDP デバイス 127.0.0.1:7100PINGを含むデータグラム →PONG 1、PONG 2、…+ TCP デバイス TCP デバイス 127.0.0.1:7200PINGを含む行 →PONG+ MQTT ブローカー MQTT ブローカー 127.0.0.1:1883lab/<name>/setへのパブリッシュ → 同じペイロードをlab/<name>/stateに保持付きでライブラリの別のエミュレーターがすでにそのポートを使っている場合は、次の空いているポートが使われます。
名前 を付けます (最大 120 文字)。
待ち受けアドレス を
IP:portで設定します。127.0.0.1はこのコンピューターにだけ応答し、0.0.0.0はネットワークにも応答します。ルールを変更し (下記参照)、何の代わりをするのかを メモ に書きます。
変更は自動的に保存されます。複製 は次の空いているポートでコピーを作ります。削除 はもう一度確認し (削除しますか?)、実行中ならエミュレーターを停止して、ライブラリから削除します。
ルールは最初から最後まで順に試され、最初に一致したものが応答します。各ルールのヘッダーには 1 行の概要が表示され、クリックするとルールを開いたり折りたたんだりできます。↑ と ↓ のボタンでルールを移動し、× で削除します。
実行する
- エミュレーターを選択して 開始 を押します。ボタンが元に戻る前にポートが開きます。すでに使われているポートや、問題のあるエミュレーターは、その時点で理由とともに拒否されます。
- システムの接続先をエミュレーターに向けます。HTTP API の場合、URL をコピー でそのアドレス (
http://127.0.0.1:18080) をコピーでき、各ルートにはそのルート自身の URL をコピーする URL をコピー ボタンがあります (パスに{{…}}テンプレートが含まれる場合を除く)。 - 受信 が埋まっていくのを確認します。
- 停止 を押すか、コンソールの帯からそのジョブを停止します。
ボタンの横の状態表示には、停止中、応答しているアドレス、またはダウン中であることが示されます。
エミュレーターは、開始したときのルールで応答し続けます。実行中に変更すると 再起動 が現れるので、押すと現在のルールで起動し直します。それまでは、ルールのヒット数は古いルールのものなので非表示になります。
ダウンさせる を押すと、復帰させる を押すまで、実行中のエミュレーターが利用できなくなります。HTTP リクエストには 503 が返され、TCP デバイスと MQTT ブローカーは接続を切断して新しい接続を拒否し、OSC と UDP のデバイスは何も応答しません。ダウンするを参照してください。
同じトランスポートの 2 つのエミュレーターは、ポートを共有できません。HTTP、TCP、MQTT のエミュレーターは TCP ポートで、OSC と UDP のエミュレーターは UDP ポートで待ち受けます。HTTP API と OSC デバイスは両方ともポート 8080 を使えますが、2 つの HTTP API は使えません。使用中のポートで 2 つ目を開始しようとすると拒否されます。
TIP
サーバーに接続したブラウザーでは、エミュレーターはサーバー上で動作します。0.0.0.0 で待ち受けるエミュレーターにはサーバーの名前で接続でき、URL をコピー はそのアドレスをコピーします。127.0.0.1 で待ち受けるものは、サーバー自身の上で動くプログラムにしか応答しません。
届いたもの
実行中、ライブ は次のものを数えます。
| カウント | 内容 |
|---|---|
| リクエスト | 届いたものすべて: リクエスト、メッセージ、行。 |
| ルールなし | どのルールにも一致しなかったもの。ルートのない HTTP リクエストにも応答は返されますが (どのルートにも一致しないリクエストを参照)、それ以外には何も返されません。 |
| 失敗 | 応答を作成または送信できなかったやり取り。 |
| ダウン中 | エミュレーターがダウンしている間に届いたもの。ダウンが設定されている場合か、ダウン中に何かが届いた場合に表示されます。ルールなし として数えられることはありません。 |
| 未配送 | MQTT のみ、発生した場合: クライアントの処理が遅れすぎて受け取れなかったメッセージ。 |
各ルールのヘッダーには、開始以降に一致した回数が表示されます。
受信 には、新しいものを上にして、最新 300 件のやり取りが一覧表示されます。
| 列 | 内容 |
|---|---|
| 時刻 | 届いた時刻。 |
| 送信元 | クライアントのアドレス。 |
| リクエスト | 届いたものをプロトコルの表記で: GET /users/7、/ping 1、POWER?。 |
| ルール | それを受け付けたルール (#2)、または —。 |
| 応答 | 返したもの: 200 OK · 37 B、/pong 3、ペイロード。障害の場合は 保留 または クローズ、応答に失敗した場合はそのエラー、ダウン中に届いた場合は ダウン。 |
| ms | 到着から応答が送り出されるまでの時間 (遅延を含む)。 |
行の ⌕ ボタン (インスペクターで開く) は、キャプチャがオンだった場合に、そのやり取りをインスペクターで開きます。0.2 秒以内に 200 件を超えるやり取りが届くと、一覧は一部を省略し、その件数を表示します。エンジンは、コマンドライン、API、MCP のために、実行中の各エミュレーターについて最新 500 件のやり取りを、届いた内容とともに保持します。
HTTP API
HTTP/1.1 サーバーです。各リクエストには、それを受け付けた最初のルートが応答します。
ルート
メソッド、パス、すべての条件が一致すると、ルートがリクエストを受け付けます。
| フィールド | 内容 |
|---|---|
| メソッド | GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS、または 任意。GET のルートは HEAD にも応答します。 |
| パス | / で始まります。:name というセグメントは任意の 1 セグメントを受け付け、{{request.params.name}} として読み取れます。最後のセグメントの * は、その下のすべてを受け付けます。末尾の / の有無は区別されず、クエリ文字列はパスに含まれません。 |
| 条件 | すべてを満たす必要があります。+ 条件 で追加します。 |
パスの例です。
| パス | 受け付ける | 受け付けない |
|---|---|---|
/health | /health、/health/ | /health/db、/Health |
/users/:id | /users/7 (params.id は 7)、/users/a%20b (a b) | /users、/users/7/orders |
/files/* | /files、/files/a、/files/a/b/c | /file、/other/files/a |
条件は、リクエストの一部 (対象) を読み取って比較します。
| 対象 | 名前 | 読み取るもの |
|---|---|---|
| ヘッダー | ヘッダー名 (大文字と小文字は区別しない) | ヘッダーの値。複数回送られたヘッダーは、値を , で連結したもの。 |
| クエリ | クエリパラメーター | その値 (デコード済み)。繰り返されている場合は最初のもの。 |
| ボディ | — | ボディ全体をテキストとして。 |
| JSON | $.user.id のような JSON パス | JSON ボディのそのフィールド。 |
比較には と等しい、と等しくない、より小さい、以下、より大きい、以上、を含む、に一致 (正規表現)、空である、空でない があります。数値は数値として、テキストは完全一致で比較します。存在しないヘッダー、パラメーター、フィールドは空として扱われます。比較できない場合 (テキストと数値の比較など)、条件は成り立ちません。
レスポンス
ルートは 1–16 個のレスポンス (レスポンス) を持ちます。
| フィールド | 内容 | 既定値 |
|---|---|---|
| ステータス | 100–599。 | 200 |
| 障害 | 応答以外のもの。障害を参照してください。 | なし — 応答する |
| 遅延 (ms) | 応答するまでの待ち時間 (0–60,000 ms)。 | 0 |
| ジッター (ms) | ランダムに最大でこの値だけ長くなります (0–60,000 ms)。 | 0 |
| 重み | ルートがランダムに応答するときの、このレスポンスの割合。そのときだけ表示されます。 | 1 |
| ヘッダー | 最大 32 個。名前にはパラメーターを、値にはテンプレートを使えます。 | なし |
| ボディ | テンプレート。書いた状態で最大 256 KiB。 | 空 |
Content-Type ヘッダーがない場合、有効な JSON のボディは application/json として、それ以外のボディは text/plain; charset=utf-8 として送られます。
レスポンスが 2 つ以上ある場合は、レスポンスの選び方 で、リクエストがどれを受け取るかを決めます。
| レスポンスの選び方 | リクエストが受け取るもの | 用途 |
|---|---|---|
| 順番に、その後は最後のもの | 1 つ目、2 つ目、…、その後はずっと最後のもの: 500、500、200、200、200… | 再試行: 2 回失敗してから成功する。 |
| 順番に繰り返し | 最後の次は再び 1 つ目: 200、500、200、500… | 規則的にときどき失敗する依存先。 |
| 重みに従ってランダム | それぞれの重みに従って抽選。重みが 8 と 2 なら、1 つ目が約 80% の割合で選ばれます。少なくとも 1 つの重みが 0 より大きい必要があります。 | 現実的な割合の失敗。 |
レスポンスを追加 で、用意されたレスポンスをルートに追加します。
| プリセット | 追加されるもの |
|---|---|
| 200 JSON | 200、{"ok":true} |
| 201 Created | 201、{"id":"{{uuid}}"}、ヘッダー Location: {{request.path}}/{{counter}} |
| 404 Not found | 404、{"error":"not found"} |
| 500 Server error | 500、{"error":"internal"} |
| 503 Unavailable | 503、{"error":"unavailable"}、ヘッダー Retry-After: 1 |
| 低速 — 2 秒 | 2000 ms 後に 200、{"ok":true} |
| 応答なし | 障害 応答なし |
| 接続切断 | 障害 接続を閉じる |
| 不正な JSON | 200、{"items":[{"id":1},{"id":2}]} に障害 不正なボディ |
障害
| 障害 | クライアントが遭遇するもの |
|---|---|
| なし — 応答する | レスポンス。 |
| 応答なし | 何も返りません。リクエストは最大 2 分間保留されてから接続が閉じられます。そのため、テストされるのはクライアント自身のタイムアウトです。遅延は適用されません。 |
| 接続を閉じる | 遅延の後、応答なしで接続が閉じられます。 |
| 不正なボディ | ステータスとヘッダーが設定された完全な HTTP 応答ですが、ボディが途中で止まり、JSON として解析できません。ボディ全体が JSON だった場合、コンテンツタイプは application/json のままです。 |
どのルートにも一致しないリクエスト
どのルートにも一致しないリクエスト の設定で、それらのリクエストが何を受け取るかを決めます。
- 404 Not found: ボディが
{"error":"no_route"}の 404。 - この応答: 自分で設定するレスポンスで、ルートのレスポンスと同じ項目をすべて持ちます。その
{{counter}}は、どのルートにも一致しなかったリクエストを数えます。
どちらの場合も、リクエストは ルールなし として数えられます。
HTTP の応答で読み取れるもの
| テンプレート | 内容 |
|---|---|
{{request.method}} | GET、POST、… |
{{request.path}} | クエリを除いたパス。 |
{{request.params.id}} | :id という名前のパスセグメント。 |
{{request.query.page}} | クエリパラメーター (デコード済み)。 |
{{request.headers.x-key}} | ヘッダー。名前は小文字で書きます。 |
{{request.body}} | ボディのテキスト。先頭の 64 KiB。 |
{{request.json.name}} | JSON ボディのフィールド。ボディが JSON で、64 KiB 以内の場合。 |
{{request.from}} | クライアントの IP:port。 |
1 MiB を超えるリクエストボディには 413 が返され、失敗 として数えられます。作成できない応答 (リクエストにないものを参照するテンプレートなど) には、ボディにエラーを含む 500 が返され、失敗 として数えられます。
OSC デバイス
届いた各メッセージ (バンドル内のメッセージは 1 つずつ個別に) には、それが一致した最初のルールが応答します。OSC ではないデータグラムは ルールなし として数えられます。
| フィールド | 内容 |
|---|---|
| アドレスパターン | OSC 1.0 のアドレスパターン: * 任意の文字列、? 任意の 1 文字、[a-z] 文字の集合、{a,b} いずれか。いずれも 1 つのセグメント内で有効です (OSC を参照)。 |
| 引数のルール | 引数に対する最大 16 個の条件。OSC を待機 と同じです (ノードを参照)。 |
| 応答する | オフ: メッセージを受け取り、何も応答しません。 |
| 応答アドレス | 応答のアドレス。テンプレートです。 |
| 応答の引数 | 最大 16 個の引数。それぞれ 型 (int、float、str、long、double、bool、blob、nil) と 値 のテンプレートを持ちます。 |
| 応答先 | 空: 送信元のアドレスとポートに返します。それ以外は IP:port。 |
| 遅延 (ms)、ジッター (ms) | それぞれ 0–60,000 ms。 |
引数の値は、テンプレートを埋めた後にその型として読み取られます。型が数値なら、{{request.args[0]}} は最初の引数を数値としてそのまま返します。bool は true、1、yes、on または false、0、no、off を受け付け、blob は hex のバイト列を受け付けます。空の値はその型のゼロ値になります。
応答はエミュレーター自身のポートから送られるので、送信に使ったポートで待ち受けているクライアントはそれを受け取れます。
OSC の応答では、{{request.address}}、{{request.args[0]}}、{{request.from}} を読み取れます。
UDP デバイス
各データグラムには、それが一致した最初のルールが応答します。
| フィールド | 内容 |
|---|---|
| 一致条件 | 任意のデータグラム、テキストを含む、正規表現に一致、バイト列を含む (hex) のいずれか。 |
| パターン | 探すテキスト、正規表現、またはバイト列。 |
| 応答 | 応答せずに受け取る、テキスト、hex のいずれかと、テンプレートで書いた応答そのもの。 |
| 応答先 | 空: 送信元に返します。それ以外は IP:port。 |
| 遅延 (ms)、ジッター (ms) | それぞれ 0–60,000 ms。 |
UDP と TCP の応答では、次のものを読み取れます。
| テンプレート | 内容 |
|---|---|
{{request.text}} | テキストとしてのペイロード。 |
{{request.match}} | 一致した部分: テキスト、正規表現の最初のグループ (なければ一致全体)、バイト列。 |
{{request.hex}} | hex バイトとしてのペイロード。先頭の 1024 バイト。 |
{{request.bytes}} | ペイロードのサイズ。 |
{{request.from}} | 送信元の IP:port。 |
テキストの応答は最大 65,507 バイトです。
TCP デバイス
プロジェクターやマトリックススイッチャーのように、TCP 接続上で行単位でやり取りするデバイスです。クライアントが送る各メッセージには、それが一致した最初のルールが応答し、応答は同じ接続で返されます。
| フィールド | 内容 |
|---|---|
| メッセージの終端 | メッセージの終わりを示すもので、各応答とグリーティングの後にも付けられます: LF (\n) (直前の \r は取り除かれます)、CR LF (\r\n)、CR (\r)、なし — チャンクごと。空行は無視されます。 |
| グリーティング | クライアントの接続時に送信します。空なら送信しません。{{request.from}} を読み取れます。 |
| 一致条件、パターン、応答 | UDP デバイスと同じです。 |
| その後、接続を閉じる | このルールの応答の後に接続を閉じます (たとえば QUIT)。 |
| 遅延 (ms)、ジッター (ms) | それぞれ 0–60,000 ms。 |
区切り文字なしで 64 KiB を超えるメッセージは、その時点のまま受け取られます。
MQTT ブローカー
平文の TCP 上で動作する小さな MQTT 3.1.1 ブローカーです。ブローカーとしての役割をひととおり果たします。クライアントは接続し、+ と # でサブスクライブし、QoS 0、1、2 でパブリッシュでき、保持メッセージと Will メッセージが機能し、同じクライアント ID による 2 つ目の接続は 1 つ目に取って代わります。セッションは常にクリーンです。セッションの保持を求めたクライアントには新しいセッションが与えられ、接続していないクライアントのためにメッセージがキューに入れられることはありません。
それに加えて、パブリッシュされたすべてのメッセージがルールと照合されます。最初に一致したルールは応答もパブリッシュします。行ったことを報告するデバイスのような振る舞いです。
| フィールド | 内容 |
|---|---|
| ユーザー名、パスワード | ユーザー名を設定すると、クライアントはそのユーザー名とパスワードで接続する必要があります。空: 誰でも接続できます。ユーザー名なしのパスワードは、MQTT 3.1.1 では送れないため拒否されます。 |
| 保持メッセージ | 最初から保持される最大 64 個のメッセージ (トピック、ペイロード、QoS)。retain 付きでパブリッシュされたかのように扱われ、サブスクライブしたクライアントが最初に受け取ります。 |
| トピックフィルター | ルールが受け付けるトピック: + は 1 階層、# は残りすべて (lab/+/set)。 |
| 一致条件、パターン | ペイロードに対する条件。UDP デバイスと同じです。 |
| 応答する | オフ: メッセージを受け取り、それ以上は何もパブリッシュしません。 |
| 応答トピック、応答ペイロード | テンプレートです。トピックには + や # を含められません。 |
| QoS、retain | 応答のものです。 |
| 遅延 (ms)、ジッター (ms) | それぞれ 0–60,000 ms。 |
MQTT の応答では、{{request.topic}}、{{request.levels[1]}} (トピックの階層、0 から数えます)、{{request.payload}}、{{request.json.state}}、{{request.match}}、{{request.qos}}、{{request.retain}}、{{request.client}} (クライアント ID)、{{request.from}} を読み取れます。
応答のテンプレート
応答は実験と同じテンプレート言語で書くので、フィールドはここでも実験でも同じ意味を持ちます。応答では次のものを読み取れます。
request: 届いたもの。上で各プロトコルについて挙げたとおりです。{{counter}}: エミュレーターの開始以降にこのルールが受け付けたメッセージの数 (今回のものを含む)。- ジェネレーター:
{{uuid}}、{{now.iso}}、ランダムな値など。ランダムな値はエミュレーターのシードから抽選されます。 - パラメーター: エミュレーターが実験の中で実行される場合、または
signallab emulate --paramで起動された場合。
応答がシークレットを読み取ることはありません。また、不明な名前は空のテキストではなくエラーになります。
一部のフィールドは、エミュレーターの起動時、何かが届く前に確定します。パス、条件、アドレスパターン、ペイロードのパターン、トピックフィルター、応答先、ヘッダーの名前、保持メッセージ、ブローカーのログイン情報です。これらにはテキストとパラメーターだけを使え、request もジェネレーターも使えません。
シードは、レスポンスのランダムな順序、ジッター、ランダムなジェネレーターを決めます。エミュレーター 画面では開始するたびに新しいシードが使われ、実験では実行のシードが使われ、signallab emulate --seed では指定したシードが使われます。
ダウンする
依存先が不安定なときにシステムがどう振る舞うかをテストするには、定期的にダウンする にチェックを入れます。
| フィールド | 内容 | 既定値 |
|---|---|---|
| 稼働時間 (ms) | 応答する時間 (10–3,600,000 ms)。 | 10,000 |
| ダウン時間 (ms) | ダウンしている時間 (10–3,600,000 ms)。 | 3000 |
| ダウン中 | HTTP のみ: ダウン中にリクエストが受けるもの。 | 503 利用不可 |
スケジュールはエミュレーターの開始とともに始まり、稼働、ダウン、稼働、ダウン…と繰り返します。ダウン中は次のようになります。
| エミュレーター | 受けるもの |
|---|---|
| HTTP | 503 利用不可: 復帰までの秒数 (最低 1) を Retry-After に設定した 503。接続を閉じる: 応答なしで接続が閉じられます。応答なし: 最大 2 分間保留されてから閉じられます。 |
| TCP デバイス | 開いている接続は 0.1 秒以内に切断され、新しい接続は届いた時点で閉じられます。 |
| MQTT ブローカー | すべての接続が切断され、新しい接続は拒否されます (CONNACK のリターンコード 3、サーバー利用不可)。 |
| OSC、UDP デバイス | 何も応答しません。 |
ダウン中に届いたものは ルールなし ではなく ダウン中 として数えられ、ルールとの照合も行われません。
ダウンさせる は、スケジュールに関係なく、復帰させる を押すまで同じことを必要なときに行います。その場合、HTTP は Retry-After なしの 503 を受けます。実験では、エミュレーターのダウン/復帰 ノードが実行の特定のステップでこれを行います (ノードと障害を参照)。
問題
編集中は、変更のたびに少し後でエミュレーターがチェックされ、開始 を押す前に、問題があればボタンの下に表示されます。問題には、その場所 (ルール、レスポンス、保持メッセージ、そしてフィールド) と、何が間違っているかが示されます。/ のないパス、コンパイルできない正規表現、request、パラメーター、ジェネレーター以外のものを参照する応答テンプレート、範囲外の値などです。開始 は問題のあるエミュレーターを拒否します。
制限
| 項目 | 上限 | 上限に達した場合 |
|---|---|---|
| エミュレーターあたりのルートまたはルール | 64 | チェック時に拒否されます。 |
| ルートあたりのレスポンス | 16 | 拒否されます。 |
| ルートあたりの条件 | 16 | 拒否されます。 |
| レスポンスあたりのヘッダー | 32 | 拒否されます。 |
| 引数の条件、応答の引数 (OSC) | それぞれ 16 | 拒否されます。 |
| 保持メッセージ (MQTT) | 64 | 拒否されます。 |
| 書いた状態のボディ、応答、グリーティング | 256 KiB | 拒否されます。 |
| 遅延またはジッター | 60,000 ms | 拒否されます。 |
| HTTP のリクエストボディ | 1 MiB | 413。 |
| HTTP の同時接続数 | 512 | それを超える接続は届いた時点で閉じられます。 |
| HTTP のリクエストヘッド | 30 秒 | クライアントはこの時間内に送る必要があります。 |
| TCP の同時接続数 | 256 | それを超える接続は届いた時点で閉じられます。 |
| 遅延を待っている OSC と UDP の応答 | 1024 | それを超えるものは破棄され、失敗 として数えられます。 |
| MQTT の同時クライアント数 | 256 | それを超えるものは届いた時点で閉じられます。 |
| MQTT のパケット | 256 KiB | そのクライアントの接続が終了します。 |
| クライアントあたりの MQTT サブスクリプション | 100 | それを超えるものは拒否されます。 |
| MQTT の保持トピック | 1000 トピック、16 MiB | 新しい保持メッセージは配信されますが、保持されません。 |
| 1 つの遅いクライアントを待つ MQTT メッセージ | 1024 メッセージ、8 MiB | クライアントはそれらを受け取れず、未配送 として数えられます。 |
レスポンスのモック化
うまくいったレスポンスからエミュレーターを作るには、次のようにします。
- HTTP 画面でリクエストを送信してレスポンスを受け取ります。または、実験の HTTP ノードで 今すぐ送信 を使います。
- レスポンスの横にある ⧉ モック化 を押します。このレスポンスをモック化 ダイアログに、作成されるルートが表示されます。
- 追加先 で、自分の HTTP エミュレーターのいずれか、または 新しいエミュレーター を選びます。
- ルートを追加 を押します。エミュレーター 画面がそのエミュレーターを表示した状態で開きます。
このルートは、リクエストのメソッドとパス (クエリを除く) に、レスポンスのステータス、ヘッダー、ボディで応答します。その 1 回のやり取りだけに属するヘッダー (Content-Length、Date、Server、ETag など) は除かれ、ボディは {{ を含んでいてもそのまま送られます。新しいエミュレーターにはこのルートだけが含まれます。既存のエミュレーターに追加した場合、ルートは先頭に置かれるので、より広いルートより先に応答します。実行中のエミュレーターは、再起動 を押すとこのルートを取り込みます。
実験から作る場合、テンプレートで書かれた URL はパターンになります。ベース ({{api}}) は除かれ、1 つのテンプレートだけのセグメント (/orders/{{order_id}}) は :order_id になり、一部だけがテンプレートのセグメントがあると、そこでパスが * で終わります。
初期セット
Signal Lab は、エミュレーターライブラリが見つからないとき、初回に 5 つのエミュレーターを書き込みます。すべてこのコンピューター上で動作します。名前とメモは、その時点のインターフェイスの言語で書かれます。
| エミュレーター | 待ち受けアドレス | 動作 |
|---|---|---|
| デモ API | 127.0.0.1:8080 | GET /health → {"status":"ok","time":…}。GET /users/:id → その ID のユーザー。POST /users → Location 付きの 201。GET /slow → 1500 ms 後に応答。/flaky → 503、503、その後はずっと 200。 |
| デモ OSC デバイス | 127.0.0.1:9100 | /ping → 回数付きの /pong。/fader/* → 受け取ったアドレス付きの /ack。/cue/* は応答せずに受け取ります。 |
| デモ UDP デバイス | 127.0.0.1:7100 | PING → PONG と回数。それ以外 → ACK とそのバイト数。 |
| デモ TCP デバイス | 127.0.0.1:7200 | CR LF で終わる行。READY であいさつし、POWER? → POWER=ON、POWER ON または POWER OFF → OK ON / OK OFF、QUIT → BYE の後に切断します。 |
| デモ MQTT ブローカー | 127.0.0.1:1883 | lab/status に online を保持します。lab/<name>/set にパブリッシュされた ON または OFF → 同じものを lab/<name>/state に保持付きで。 |
シグナルライブラリの初期セットにある サービスは稼働中? シグナルは、デモ API のアドレス http://127.0.0.1:8080/ に問い合わせます。/ のルートはないので、404 を受け取ります。
ライブラリファイル
ライブラリはデータフォルダー内の emulators.json です (ファイルを参照)。一覧の下の件数にポインターを合わせると、そのパスが表示されます。最後の変更から 0.7 秒後に一時ファイルを経由して全体が書き込まれるので、書き込みに失敗しても以前のファイルが残ります。ファイルを読み取れない場合、一覧にはパス、行、列とともにエラーが表示され、ファイルはそのまま残されます。修正して ファイルを再読み込み を押してください。手作業で編集した後も ファイルを再読み込み を押します。ファイルがなければ、初期セットが再び書き込まれます。
{
"version": 1,
"emulators": [
{
"id": "orders-api",
"note": "Stands in for the orders service.",
"emulator": {
"name": "Orders API",
"bind": "127.0.0.1:18080",
"protocol": "http",
"routes": [
{ "method": "GET", "path": "/orders/:id",
"responses": [{ "body": "{\"id\":\"{{request.params.id}}\",\"state\":\"open\"}" }] },
{ "method": "POST", "path": "/orders", "order": "sequence",
"responses": [{ "status": 503 }, { "status": 201, "body": "{\"id\":\"{{uuid}}\"}" }] }
],
"outage": { "up_ms": 20000, "down_ms": 2000, "fault": "unavailable" }
}
}
]
}emulator オブジェクト単体も、signallab emulate が読み込めるドキュメントです。
実験とスクリプトで使う
- 実験では、エミュレーター ノードが最初のステップの前にそのエミュレーターを開き、実行が終わるまで応答します。受信したものはレポートで集計されます。そこでの HTTP エミュレーターは HTTP リクエストを待機 (ノード) が待ち受ける対象でもあり、OSC や UDP のエミュレーターは実行の待機とポートを共有します。1 つの実験の中で、同じトランスポートの 2 つのエミュレーターがポートを共有することはできません。ノードと障害を参照してください。
signallab emulateは、ファイルまたはこのライブラリのエミュレーターを、Ctrl+C を押すか--forの時間が過ぎるまで実行し、応答した内容を出力します。コマンドラインを参照してください。
関連項目
- インスペクター: すべてのやり取りをデコードして表示します。
- ネットワーク劣化: システムとエミュレーターの間の品質の悪いネットワーク。
- データとテンプレート