zplCloud Blog
Impressão de etiquetas com Azure Service Bus: a fila como gatilho
Dois formatos de payload, uma fila: um registro JSON que preenche um design ou ZPL bruto em um envelope. PeekLock, para que nada se perca e nada seja impresso duas vezes.
A fila já é o gatilho
Se seus sistemas já conversam via Azure Service Bus, o trabalho de impressão é uma mensagem como qualquer outra. Uma assinatura Data Streaming do tipo Service Bus consome uma fila ou uma assinatura de tópico e imprime cada mensagem - sem trabalho de polling, sem middleware de impressão, sem servidor de impressão Windows entre o barramento e a impressora.
O interessante é que uma mensagem pode ser uma de duas coisas, e o zplCloud decide por mensagem:
- Um registro JSON - as chaves do objeto preenchem os bindings de um design de etiqueta. Use quando o remetente conhece os dados, não o layout.
- Um envelope ZPL - um objeto JSON carregando ZPL pronto. Use quando o remetente já produz ZPL e só precisa que ele chegue a uma impressora.
Ambos passam pela mesma assinatura; você não configura um modo.
Configurando a assinatura
| Campo | Valor |
|---|---|
| Tipo | Service Bus |
| Configuração de conexão | a string de conexão do namespace |
| Tópico | nome da fila, ou topic/Subscriptions/nomeAssinatura |
| Design de etiqueta | o design usado para registros JSON |
| Impressora | a impressora de destino padrão |
A string de conexão é armazenada criptografada com AES em repouso.
Fila ou tópico é decidido pelo campo Topic, por convenção: se o valor contém /Subscriptions/, é tratado como topic/Subscriptions/nomeAssinatura; caso contrário, é um nome de fila. Você também pode deixá-lo vazio e colocar EntityPath=printer na string de conexão.
Assinaturas não são criadas automaticamente. Crie a assinatura do tópico uma vez no portal, Service Bus Explorer ou emulador (topic.1/Subscriptions/subscription.1); o zplCloud só a consome.
Ao contrário da integração Kafka, o Service Bus roda somente no lado cloud - o consumidor vive no backend e conecta para fora. Não há variante agente on-prem, porque um namespace Service Bus é acessível pela internet de qualquer forma.
Payload A - um registro JSON para um design
{ "ean": "4006381333930", "qty": 2, "dest": "Ramp 4" }
As chaves correspondem aos bindings do design por nome. Chaves sem binding são ignoradas; bindings sem chave são renderizados vazios.
Se o corpo não for JSON, todo o texto é vinculado como $message - suficiente para uma etiqueta de campo único.
Um erro de render nomeia o campo que o causou em vez de lhe dar uma mensagem SDK:
ZPL-Renderfehler bei qty: Wert 'zwei' → ...
Isso geralmente é um problema de tipo ou comprimento: um campo numérico alimentado com uma palavra, ou um valor mais longo do que o campo pode conter.
Payload B - ZPL bruto em um envelope
Quando o remetente já tem o ZPL, envolva-o:
{
"schemaVersion": 1,
"zpl": "^XA^FO50,50^A0N,40,40^FDFrom the bus^FS^XZ",
"printer": "*"
}
As regras para isso ser tratado como envelope são deliberadamente rígidas:
- o corpo deve ser um objeto JSON,
- deve ter uma propriedade
zplque seja uma string não vazia, - e deve adicionalmente carregar
printer(string) ouschemaVersion(número).
A última condição é a importante. Um registro de dados comum que por acaso contém um campo chamado zpl não é sequestrado e enviado bruto à impressora - ele ainda passa pelo caminho do design. Se você quer o comportamento de envelope, diga explicitamente com printer ou schemaVersion.
No modo envelope, o design não é tocado: o ZPL vai para a impressora byte por byte.
Escolhendo a impressora por mensagem
O printer do envelope substitui a impressora da assinatura para aquela mensagem. Dois sentinelas transmitem:
"*"ou"all"- todas as impressoras do workspace, Weblink e impressoras de agente remoto igualmente.
Cada destino conta como uma etiqueta própria contra sua cota, então uma transmissão para oito impressoras são oito etiquetas. Esse é o modelo certo para um aviso de troca de turno; é um erro caro para uma etiqueta por pedido.
Semântica de entrega: PeekLock, e o que acontece quando uma impressão falha
Aqui é onde uma integração de fila é confiável ou não. O receptor roda em modo PeekLock com PrefetchCount = 0 - receber não é excluir, e nenhuma mensagem é armazenada em buffer no processo, então parar ou reiniciar a assinatura nunca engole nem duplica um lote.
| Resultado | O que acontece com a mensagem |
|---|---|
| Impressa | Complete - a mensagem sai do barramento |
| Impressão falhou, entrega < 3 | Abandon - reentregue, depois um backoff de 10 s antes da próxima recepção |
| Impressão falhou, entrega ≥ 3 | Dead-letter com motivo Print-Fehler (MaxDeliveryCount erreicht) e o erro como descrição |
Duas consequências que valem ser ditas claramente:
- Uma falha de impressão não para o consumidor. Ao contrário do caminho Kafka, a assinatura continua rodando e tentando; só a mensagem individual escala para a fila de mensagens mortas.
- Sucesso é "os bytes chegaram ao socket da impressora". Uma Zebra nunca confirma uma etiqueta ZPL, então esperar uma confirmação significaria um travamento de 20 segundos e uma impressão duplicada.
Completeacontece quando o envio foi bem-sucedido - a coluna de debug mostrasent (no response)exatamente para este caso.
Como mensagens falhas são dead-lettered em vez de tentadas para sempre, a DLQ vira sua fila de etiquetas que não saíram. Essa é uma lista sobre a qual você pode agir, que é todo o ponto.
Keepalive ocioso
Se nada chegar por 60 segundos, a assinatura envia um comando de ativação para a impressora de destino. Impressoras Link-OS caem em estado de baixo consumo, e sem isso a primeira mensagem após um período silencioso paga a latência de ativação. O keepalive roda fire-and-forget para não bloquear o loop de recepção e causar acúmulo.
O que você vê enquanto roda
Cada assinatura mantém um ring buffer dos últimos 50 mensagens com a prévia do valor, o resultado de impressão e um rastreio de ponta a ponta:
bus=12ms design=3ms zpl=18ms print=64ms total=85ms
bus é o tempo entre o enfileiramento e a recepção - essa é a latência da fila, não sua. A coluna de debug adicionalmente registra a impressora, o número de bytes do ZPL, o status HTTP e a resposta bruta.
Mensagens que falham também são escritas em um log de erros persistente, mas somente na primeira entrega. Sem essa proteção, os retries do próprio Service Bus arquivariam a mesma mensagem ruim três vezes.
Cotas
Cada etiqueta em streaming conta como uma renderização contra o plano do dono da assinatura. Duas mensagens distintas aparecem quando você esgota:
Render-Limit erreicht (…/… Labels diesen Monat, Tarif …)- o orçamento mensal de renderizações,Streaming-Kontingent erreicht (…)- o teto de streaming especificamente.
Starter inclui streaming para testes, limitado a 100 etiquetas em streaming por mês. Pro inclui 2 endpoints de streaming (Kafka ou Service Bus); cada endpoint adicional custa € 10 por mês. Veja a página de preços.
Qual payload você deve enviar
| Registro JSON | Envelope ZPL | |
|---|---|---|
| O remetente precisa saber | nomes de campos | o layout completo da etiqueta |
| Mudanças de layout | edite o design, remetentes inalterados | cada remetente deve ser reimplantado |
| Impressora por mensagem | impressora da assinatura | printer, incl. transmissão * |
| Fontes, códigos de barras, RFID | tratados pelo design | sua responsabilidade |
Envie registros se puder. O design permanece editável por quem é dono da etiqueta, e uma mudança de layout não exige um release no sistema que publica as mensagens. Envie envelopes quando o ZPL sai de um sistema que você não controla, ou quando uma mensagem precisa alcançar várias impressoras ao mesmo tempo.