zplCloud Blog
zplCloud と Azure Service Bus でラベルを印刷する: ZPL でも JSON ペイロードでも
ペイロードは 2 種類、キューは 1 つ。デザインを埋める JSON レコードか、エンベロープに入れた生の ZPL です。PeekLock なので、何も失われず、二重に印刷されることもありません。
キューがそのままトリガーになる
システム間がすでに Azure Service Bus でやり取りしているなら、印刷ジョブも他と同じ 1 通のメッセージにすぎません。Service Bus タイプの Data Streaming サブスクリプションはキューまたはトピックサブスクリプションを消費し、すべてのメッセージを印刷します。ポーリングジョブも、印刷ミドルウェアも、バスとプリンターの間に置く Windows プリントサーバーも不要です。
興味深いのは、メッセージが次の 2 つのどちらかであり得ること、そして zplCloud がメッセージごとにそれを判断することです。
- JSON レコード: オブジェクトのキーがラベルデザインのバインディングを埋めます。送信側がレイアウトではなくデータを把握している場合に使います。
- ZPL エンベロープ: 完成した ZPL を運ぶ JSON オブジェクトです。送信側がすでに ZPL を生成していて、あとはプリンターに届けるだけの場合に使います。
どちらも同じサブスクリプションを通ります。モードを設定する必要はありません。
サブスクリプションを設定する
| 項目 | 値 |
|---|---|
| タイプ | Service Bus |
| 接続設定 | 名前空間の接続文字列 |
| トピック | キュー名、または topic/Subscriptions/subscriptionName |
| ラベルデザイン | JSON レコードに使用するデザイン |
| プリンター | 既定の出力先プリンター |
接続文字列は保存時に AES で暗号化されます。
キューかトピックかは Topic フィールドの値で決まります。慣例として、値に /Subscriptions/ が含まれていれば topic/Subscriptions/subscriptionName として扱われ、それ以外はキュー名として扱われます。このフィールドを空のままにして、接続文字列に EntityPath=printer を入れることもできます。
サブスクリプションは自動的には作成されません。トピックサブスクリプションはポータル、Service Bus Explorer、またはエミュレーター (topic.1/Subscriptions/subscription.1) で一度作成してください。zplCloud はそれを消費するだけです。
Kafka 連携とは異なり、Service Bus はクラウド側でのみ動作します。コンシューマーはバックエンドに存在し、送信方向で接続します。オンプレミスのエージェント版はありません。Service Bus の名前空間はいずれにせよインターネットから到達できるためです。
ペイロード A: デザイン用の JSON レコード
{ "ean": "4006381333930", "qty": 2, "dest": "Ramp 4" }
キーは名前でデザインのバインディングに対応付けられます。バインディングのないキーは無視され、キーのないバインディングは空でレンダリングされます。
本文がまったく JSON でない場合は、テキスト全体が $message にバインドされます。単一フィールドのラベルにはこれで十分です。
レンダリングエラーは、SDK のメッセージをそのまま返すのではなく、原因となったフィールド名を示します。
ZPL-Renderfehler bei qty: Wert 'zwei' → ...
これはたいてい型か長さの問題です。数値フィールドに単語が渡された、あるいは値がフィールドに収まる長さを超えている、といった場合です。
ペイロード B: エンベロープに入れた生の ZPL
送信側がすでに ZPL を持っている場合は、次のように包みます。
{
"schemaVersion": 1,
"zpl": "^XA^FO50,50^A0N,40,40^FDFrom the bus^FS^XZ",
"printer": "*"
}
これがエンベロープとして扱われる条件は、意図的に厳しくしてあります。
- 本文が JSON のオブジェクトであること、
- 空でない文字列の
zplプロパティを持つこと、 - さらに
printer(文字列) またはschemaVersion(数値) を併せ持つこと。
最後の条件が重要です。たまたま zpl という名前のフィールドを含む通常のデータレコードが横取りされ、生のままプリンターへ送られることはありません。そうしたレコードはこれまでどおりデザイン経由で処理されます。エンベロープとしての動作を望む場合は、printer か schemaVersion で明示してください。
エンベロープモードではデザインには一切触れません。ZPL はバイト単位でそのままプリンターへ送られます。
メッセージごとにプリンターを選ぶ
エンベロープの printer は、そのメッセージに限りサブスクリプションのプリンター設定より優先されます。ブロードキャスト用に 2 つの特別な値があります。
"*"または"all": ワークスペース内のすべてのプリンター。Weblink プリンターもリモートエージェントのプリンターも同様に含みます。
送信先はそれぞれ 1 枚のラベルとして割り当て量に計上されるため、8 台へのブロードキャストはラベル 8 枚分です。シフト交代の掲示にはこれが正しいモデルですが、注文ごとのラベルでは高くつく間違いになります。
配信のセマンティクス: PeekLock と、印刷が失敗したときの挙動
キュー連携が信頼できるかどうかが決まるのがここです。レシーバーは PeekLock モード、PrefetchCount = 0 で動作します。受信は削除ではなく、プロセス内にメッセージがバッファリングされることもないため、サブスクリプションを停止しても再起動しても、バッチが飲み込まれたり二重に処理されたりすることはありません。
| 結果 | メッセージの扱い |
|---|---|
| 印刷成功 | Complete: メッセージはバスから消えます |
| 印刷失敗、配信回数 < 3 | Abandon: 再配信され、次の受信までに 10 秒のバックオフが入ります |
| 印刷失敗、配信回数 ≥ 3 | 理由 Print-Fehler (MaxDeliveryCount erreicht) とエラー内容を説明に付けてデッドレターへ |
はっきり書いておくべき帰結が 2 つあります。
- 印刷の失敗でコンシューマーは止まりません。 Kafka の経路とは異なり、サブスクリプションは動き続けて再試行します。デッドレターキューへエスカレートするのは個々のメッセージだけです。
- 成功とは「バイト列がプリンターのソケットに届いた」ことです。 Zebra は ZPL ラベルの完了を返さないため、確認を待つと 20 秒の停滞と二重印刷を招きます。
Completeは送信が成功した時点で行われ、デバッグ列にはまさにこの場合を表すsent (no response)が表示されます。
失敗したメッセージは延々と再試行されるのではなくデッドレターに送られるため、DLQ が「出てこなかったラベル」の一覧になります。対処できる一覧になること、それがすべての狙いです。
アイドル時のキープアライブ
60 秒間何も届かないと、サブスクリプションは対象プリンターへウェイクコマンドを送ります。Link-OS プリンターは低電力状態に入るため、これがないと静かな時間の後の最初のメッセージがウェイクアップの待ち時間を負担することになります。キープアライブは受信ループをブロックして滞留を起こさないよう、送りっぱなしで実行されます。
稼働中に見えるもの
各サブスクリプションは直近 50 件のメッセージをリングバッファーに保持し、値のプレビュー、印刷結果、エンドツーエンドのトレースを表示します。
bus=12ms design=3ms zpl=18ms print=64ms total=85ms
bus はエンキューから受信までの時間、つまりこちら側ではなくキューの遅延です。デバッグ列にはさらに、プリンター、ZPL のバイト数、HTTP ステータス、生のレスポンスが記録されます。
失敗したメッセージは永続的なエラーログにも書き込まれますが、最初の配信のときだけです。この保護がないと、Service Bus 自身の再試行によって同じ不正なメッセージが 3 回記録されてしまいます。
割り当て量
ストリーミングされたラベルはすべて、サブスクリプション所有者のプランに対するレンダリングとして計上されます。上限に達すると、次の 2 つの異なるメッセージが表示されます。
Render-Limit erreicht (…/… Labels diesen Monat, Tarif …): 月間のレンダリング予算、Streaming-Kontingent erreicht (…): ストリーミング固有の上限。
Starter にはテスト用のストリーミングが含まれ、月あたり 100 通のストリーミングラベルが上限です。Pro には 2 つのストリーミングエンドポイント (Kafka または Service Bus) が含まれ、追加のエンドポイントは月 10 € です。料金ページを参照してください。
どちらのペイロードを送るべきか
| JSON レコード | ZPL エンベロープ | |
|---|---|---|
| 送信側が知っている必要があるもの | フィールド名 | ラベルレイアウト全体 |
| レイアウトの変更 | デザインを編集するだけで、送信側は変更不要 | すべての送信側を再デプロイ |
| メッセージごとのプリンター | サブスクリプションのプリンター | printer、* のブロードキャストも可 |
| フォント、バーコード、RFID | デザイン側で処理 | 自分の責任 |
可能ならレコードを送ってください。ラベルを担当する人がデザインを編集できる状態が保たれ、レイアウトの変更のためにメッセージを発行する側のシステムをリリースし直す必要もありません。ZPL が自分の管理下にないシステムから出てくる場合や、1 通のメッセージを複数のプリンターへ同時に届けたい場合は、エンベロープを送ってください。