仓库电脑不打开业务页,也能接到 ERP/WMS 任务并静默出纸------这叫远程打印(或服务端推送打印)。本地客户端变成「打工进程」:连你们的服务,拉任务,打完(或失败)再回报。
远程打印里第二个选型题,是传输方式:WebSocket 长连接,还是 HTTP 轮询?
两边都能用。选错的代价通常是:内网防火墙扯皮一周、断线后漏单、或轮询把服务端打高同时出纸延迟难看。
本文讲工程选型与落地要点。会提到本机客户端配合 web-print-pdf 生态的常见做法,但远程链路本身往往是「服务端约定消息格式 + 客户端填消费地址」,不一定在远程路径上调用前端 npm API。不放外链。
一、远程打印在解决什么问题
本地静默(页面开着,点按钮出纸)解决不了这些场景:
- 手机/平板录单,仓库 PC 出纸
- 服务端自动过账后触发面单,操作员不必守着网页
- 多工位抢单,任务路由到指定打印机所在电脑
- 浏览器页签关掉后仍要继续打(客户端托盘在即可)
共同架构:
业务系统 / 中间服务(任务存储与暴露)
↓ WebSocket 或 HTTP
工位上的本地打印客户端
↓ 系统打印栈
物理打印机
关键判断:
- 浏览器页里的 npm 调用:适合「人在页面上点打印」
- 远程消费接口:适合「人不必开着业务页」
两者可并存:补打、预览走页面 SDK;波次走远程。
二、WebSocket 长连接:适合什么
2.1 优势
- 服务端有新任务可以立刻推,延迟低
- 适合波次、厨打、叫号出票等「来了就打」
- 双向通信方便:推任务、回收执、下发配置
2.2 代价
- 连接生命周期要管理:断线重连、心跳、鉴权过期
- 部分企业网、代理、安全软件对长连接不友好
- 服务端要扛大量并发连接(工位多时)
- 排查比 HTTP 略难:要看连接是否还在、是否半死不活
2.3 更合适的信号
- 内网环境相对可控
- 延迟敏感(厨打、接力出票)
- 已有 WebSocket 基础设施(消息网关、统一推送)
- 工位数量级可评估,连接数在运维掌握中
三、HTTP 轮询:适合什么
3.1 优势
- 防火墙与网关策略通常更好讲:就是周期性请求
- 实现与排障心智简单:请求、响应、状态码
- 对「偶发任务、可接受数秒延迟」足够
- 某些只允许出站 HTTP 的环境更易落地
3.2 代价
- 延迟≈轮询间隔;间隔短则服务端与客户端都更忙
- 空转请求多,工位上千时要认真做缓存与条件请求
- 服务端推送感弱,要靠「任务可见性」与拉取游标设计
3.3 更合适的信号
- 跨网、专线、多层代理,长连接总出问题
- 任务不算实时,3~10 秒延迟可接受
- 运维团队更熟 HTTP,监控体系已按请求指标建好
- 安全设备明确对 WebSocket 升级不友好
四、别把「协议」当成唯一差别
真正决定成败的,往往是协议之外的约定:
4.1 消息格式要固定
任务里至少有:
- 任务 ID(幂等)
- 内容类型(HTML / PDF URL / Base64 等)
- 打印机路由信息(打印机名或工位绑定)
- 票种 / 业务单号
- 创建时间与过期时间(尤其 PDF 签名 URL)
格式变来变去,客户端和服务端会对不上,远程打印比本地点按钮更容易变成「偶发」。
4.2 消费模型要明确
- 拉到即锁定?还是允许多工位竞争?
- 打成功如何 ACK?失败是否回队?
- 超时未 ACK 是否重新投递?(重新投递就要防双打)
WebSocket 和 HTTP 都要回答这些问题;只换协议解决不了双打。
4.3 工位路由
远程打印最怕打错柜台。推荐:
- 客户端配置「工位 ID / 仓库 ID」
- 服务端按工位过滤任务
- 打印机名在工位本地配置,而不是让远程任务写死易变的系统打印机名(除非你们设备命名规范极强)
4.4 与页面 SDK 的分工
web-print-pdf 一类 npm 包:适合业务页本地触发、联调预览、管理端补打。
远程路径:客户端直接消费你们暴露的接口;不要幻想「服务端替用户执行浏览器里的 npm」。
本地补打示例(人在页面上)可以是:
bash
npm install web-print-pdf
js
import webPrintPdf from 'web-print-pdf'
await webPrintPdf.printPdfByUrl(
task.pdfUrl,
{},
{ printerName: localPrinterName, copies: 1 },
{ action: 'print' }
)
远程波次则走客户端配置的消费地址------两套入口,一种出纸能力。
五、断线、重连、漏单:协议都躲不过
无论 WebSocket 还是 HTTP,都要设计:
-
客户端离线期间任务去哪
服务端持久化,上线后补偿拉取;不能只推一次就丢。
-
重连风暴
全仓断电恢复后,所有工位同时重连/狂拉,服务端可能雪崩。需要抖动(jitter)与限流。
-
半成功
已出纸但 ACK 丢失 → 重投就会双打。要用业务单号幂等或「出纸成功凭证」收敛。
-
时钟与过期
PDF URL 过期、任务 TTL,导致重连后一批全失败。补偿拉取时要过滤不可打印任务并标失败原因。
这些比「我们上不上 WebSocket」更影响夜班生死。
六、安全与内网策略(选型时常被低估)
- 客户端到服务端:鉴权(令牌、工位证书、IP 允许名单)
- 任务内容是否含敏感收件人信息:传输要加密(HTTPS / WSS)
- 公网 SaaS 打到门店电脑:还要考虑门店上行网络质量与安全准入
- 仅内网:HTTP 明文有时仍被接受,但要清楚风险谁签字
协议选择经常被安全设备绑架:不是 WS「不好」,是环境不允许。先做一次连通性 PoC,再写进方案,避免评审通过后实施卡死。
七、决策表
| 条件 | 更倾向 WebSocket | 更倾向 HTTP 轮询 |
|---|---|---|
| 要秒级出纸(厨打、叫号) | 是 | 勉强(间隔要很短,成本高) |
| 内网可控、已有 WS 网关 | 是 | 可用但不必要 |
| 多层代理 / 对 WS 不友好 | 否 | 是 |
| 任务稀疏、延迟数秒可接受 | 可用 | 更简单 |
| 工位规模很大、连接运维弱 | 慎 | 往往更易控 |
| 团队排障习惯 | 熟推送体系 | 熟 HTTP 监控 |
也可以混合:
- 默认 HTTP 轮询保底
- 对延迟敏感的票种走 WS
- 或 WS 断线期间降级为轮询
混合会增加复杂度,只在有明确痛点时上。
八、落地顺序(避免一上来赌协议)
- 先固定任务 JSON 与状态机(含幂等、ACK、失败原因)
- 单工位用最容易打通的方式 PoC(常常是 HTTP)
- 量出延迟与失败率是否达标
- 不达标再引入 WS,或优化轮询间隔与条件请求
- 最后才做多仓、多票种路由与监控大盘
很多项目第一步就争论 WS 和 HTTP,第三步才发现 PDF URL 过期和双打没设计------顺序反了。
九、和本地静默的边界(再强调一次)
| 能力 | 页面 + npm SDK | 远程消费 |
|---|---|---|
| 人在浏览器点打印 | 最合适 | 不必 |
| 页签关闭仍出纸 | 不保证 | 客户端在即可 |
| 手机触发仓内出纸 | 不合适 | 合适 |
| 联调预览版式 | 合适 | 通常较弱 |
| 指定本机打印机 | 支持 | 支持(工位配置) |
远程不是「更高级的静默」,是触发源从页面换成了服务端任务。底层仍要本地客户端碰打印机------纯网页远程直打 USB 机,在通用浏览器里依然不成立。
十、小结
WebSocket 低延迟、适合推送型现场;HTTP 轮询简单、适合受限网络与可延迟任务。协议可以选,但任务持久化、幂等、ACK、工位路由、断线补偿 不能省。页面侧 web-print-pdf 解决本地触发与补打体验;远程波次靠客户端消费你们暴露的接口。
选型一句话:
延迟敏感且网络友好 → 优先 WebSocket;环境刁钻或任务稀疏 → 优先 HTTP 轮询;先把任务语义定死,再锁协议。
包名:web-print-pdf(本地触发/补打)。本文不放外链,远程消息字段与客户端配置以产品文档为准,需要时自行搜索包名。