Chapter 5. WebSocket Protocol & JS SDK

wxprint Last Updated: 2026-10-25 10:56 Views: 33

Chapter 5. WebSocket Protocol & JS SDK

5.1 Connection and authentication

ws://127.0.0.1:8899/ws?token=T        # plain
wss://host:8898/ws?token=T            # TLS (required when the page is https)
  • One message is one submission: pass the template and data (or a data URL) directly; the server accepts, renders, and prints. The wire protocol has no method envelope.
  • Queries (printers/templates/job details/cancel) always go through REST; WS carries submissions and events only.
  • Heartbeats use protocol-level ping/pong frames (browsers answer automatically).
  • Reconnection: after reconnecting, query in-flight jobs over REST GET /api/jobs/{id} (events are not replayed); cancellation goes through REST.

5.2 Submission message (client → server)

Field Type Required Description
type string ✓ "print" (to paper) or "preview" (render only)
request_id string ✓ Client-generated; correlates accepted/done/error
template string | object ✓ As REST: id / {url} / inline object
data any | object ✓ As REST: inline (array = batch) / {json}/{path} / {url,headers,timeout_s}
printer string Printer name (omitted = system default)
copies / copies_per_record / collate / pages As REST /api/print
options object As REST

type:"preview" is equivalent to REST POST /api/print with "preview": true: when done, the tray pops the native preview window (Section 9.3); without a tray, the web component /preview/{job_id} applies.

{ "type": "print", "request_id": "r1",
  "template": "sf-waybill-100x93",
  "data": { "url": "https://erp.example.com/api/waybill/12345" },
  "printer": "HP-LaserJet-M1005", "copies_per_record": 3 }

5.3 Event messages (server → client)

type Trigger Key fields
accepted Submission accepted request_id, job_id, total_pages
job Job state change / progress job_id, status, page_done, total_pages (broadcast)
printer Printer state change name, state (broadcast)
done Job finished request_id, job_id, status
error Submission failed request_id, code, message (codes as in Section 4.2)
{ "type": "accepted", "request_id": "r1", "job_id": "j_01J8…", "total_pages": 6 }
{ "type": "job", "job_id": "j_01J8…", "status": "printing", "page_done": 4, "total_pages": 6 }
{ "type": "printer", "name": "HP-LaserJet-M1005", "state": "out_of_paper" }
{ "type": "done", "request_id": "r1", "job_id": "j_01J8…", "status": "done" }
{ "type": "error", "request_id": "r1", "code": "E_RENDER", "message": "…" }

5.4 Raw protocol usage (browser)

Prefer the JS SDK (Section 5.5); the raw protocol is for understanding and debugging:

const ws = new WebSocket("ws://127.0.0.1:8899/ws?token=T");
ws.onopen = () => ws.send(JSON.stringify({
  type: "print", request_id: "r1",
  template: "sf-waybill-100x93",
  data: { url: "https://erp.example.com/api/waybill/12345" },
  copies_per_record: 3 }));
ws.onmessage = (e) => {
  const m = JSON.parse(e.data);
  if (m.type === "accepted") console.log("job:", m.job_id, m.total_pages);
  if (m.type === "job")     console.log(m.status, m.page_done + "/" + m.total_pages);
  if (m.type === "done")    console.log("finished");
  if (m.type === "error")   console.error(m.code, m.message);
};

5.5 JS SDK (wxprint.js) reference

The server hosts http://127.0.0.1:8899/sdk/wxprint.js (UMD/ESM), wrapping the WS protocol and the script API into methods. Include it with:

<script src="http://127.0.0.1:8899/sdk/wxprint.js"></script>

Constructor options

const wp = new wxprint.WxPrint({ host: "127.0.0.1", port: 8899,
                                 tlsPort: 8898, token: "T",
                                 reconnectDelay: 2000 });
// or the factory: const wp = await wxprint.connect({ token: "T" });
Option Type Default Description
host string location.hostname Service host
port int 8899 Plain port (http/ws)
tlsPort int 8898 TLS port (used automatically when the page is https)
token string null Auth token
reconnectDelay int 2000 Reconnect interval (ms)

Direct-print methods (wrapping the WS protocol)

Method Parameters Returns Description
connect() — Promise Establish the connection (auto-reconnect after drops at reconnectDelay; submissions made while offline are queued and flushed on reconnect)
close() — — Close the connection (no more reconnects)
print(req) fields as in Section 5.2 Promise<{job_id, total_pages}> Submit to paper
preview(req) same Promise Submit a preview (tray window pops on done)
saveas(req, format) req + `“pdf” “png” “zip”`
printers() — Promise Printer list (REST pass-through)
job(jobId) string Promise Job status (REST pass-through)
onJob(cb) (ev) => void this Subscribe to job events (state changes + progress)
onPrinter(cb) (ev) => void this Subscribe to printer events

Programmatic building (DocBuilder, wrapping the script API)

wp.document() returns a chainable builder whose verbs map one-to-one to Chapter 6:

Method Parameters Description
init(taskName) string Task name (shown in the print queue)
pagesize(w, h, opts?) mm + {orientation, continuous} Page size; h=0 fits the content height
loadData(data) object | array Inline data (array = batch)
loadJSON(textOrPath) string JSON text or a server-side file path
loadURL(url, opts?) url + {headers, timeout_s} Fetched at run time
addText(el) / addHtml(el) / addTable(el) element object Fields as in Sections 7.5–7.7
addBarcode(el) / addQrcode(el) / addImage(el) element object Fields as in Sections 7.8–7.10
addRect(el) / addLine(el) / addChart(el) element object Fields as in Section 7.4
newpage() — Force a page break
print(params?) {printer, copies, …} Submit to paper
preview() — Submit a preview

Complete example

// ① Direct printing + event subscription
const wp = new wxprint.WxPrint({ token: "T" });
wp.onJob(ev => console.log(ev.status, ev.page_done + "/" + ev.total_pages));
wp.onPrinter(ev => console.log(ev.name, ev.state));
await wp.print({ template: "sf-waybill-100x93",
                 data: { url: "https://erp.example.com/api/waybill/12345" },
                 printer: "HP-LaserJet-M1005", copies_per_record: 3 });

// ② Programmatic building (no template file)
const doc = wp.document();
doc.init("Delivery note")
   .loadURL("https://erp.example.com/api/order/SO-1024")
   .pagesize(210, 297)
   .addText({ x: 20, y: 15, w: 80, h: 8, text: "{{title}}",
              font: { size_pt: 16, weight: 700 } })
   .addBarcode({ x: 20, y: 30, w: 60, h: 10,
                 symbology: "code128", content: "{{order_no}}" })
   .newpage()
   .addHtml({ x: 0, y: 0, w: 210, h: 297,
              html: "<table>{% for it in items %}<tr><td>{{it.name}}</td></tr>{% endfor %}</table>" });
await doc.print({ printer: "HP-LaserJet-M1005", copies: 2 });

5.6 WS or REST?

Scenario Recommendation
Web submission + live progress/completion callbacks WS (or the SDK’s print)
Backend one-shot submission, status on demand REST + polling
Cancel / detail queries REST (WS carries no queries)
HTTPS pages wss (the SDK switches to the TLS port automatically)
← Previous Article Chapter 6. Script API Reference Next Article → Chapter 4. HTTP API Reference

Comments

No comments yet