WebSocket仅是通信管道,真正打印由本地插件执行;连接地址通常为ws://127.0.0.1:12705或ws://localhost:13528;需先调getPrinters获取列表,再发print指令;指令须带唯一ID并处理重连与幂等性。

WebSocket 本身不直接驱动打印机,它只是通信管道;真正执行打印的是本地插件(如微信小店打印组件、康虎云打印代理等)——你必须先确认该插件已安装并正常运行,否则任何 WebSocket 连接都会失败。
连接本地打印插件的 WebSocket 地址怎么写
绝大多数桌面打印代理(包括微信小店、康虎、HttpPrinter 等)默认在本地启动一个 WebSocket 服务,地址固定为 ws://127.0.0.1:12705 或 ws://localhost:13528。不要硬编码成生产域名或远程 IP。
- 微信小店打印组件:用
ws://127.0.0.1:12705(官方文档明确指定) - 部分旧版插件(如某些 HttpPrinter 封装):用
ws://localhost:13528 - 开发时可加
console.log打印event.target.url验证实际连接地址 - 生产环境若需加密,必须改用
wss://+ 自签名证书 + 插件支持,否则浏览器会拦截
发送打印指令前必须先获取打印机列表
插件不会主动推送可用打印机,前端必须显式发命令拉取。常见错误是跳过这步,直接发 print 指令,结果插件返回 "printer not found" 或静默丢弃。
- 连接成功后立即发送:
{"cmd": "getPrinters", "requestID": "uid_abc123"} - 监听
onmessage,检查result.cmd === "getPrinters"再赋值给下拉框 - 如果返回空数组
[],说明系统未添加打印机(不是插件问题,是 Windows/macOS 未在“设置→打印机”里配置) - 某些插件要求首次调用前先发
handshake包,例如:{"type":"handshake","printerId":"PRN-2024-XXXX"}
自动触发打印的关键:避免 window.print() 干扰
很多人误以为 WebSocket 收到指令后该调 window.print(),这是错的——那只会弹浏览器原生对话框,和本地插件完全无关。真正的“自动打印”是指令发给插件后,由它调操作系统 API 完成。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 正确流程:组装好面单 HTML 或 PDF base64 → 封装进
print指令 payload →websocket.send() - 典型 payload 结构(微信小店兼容):
{"cmd":"print","printerName":"HP LaserJet MFP","content":"订单号:123","contentType":"html"} - 不要在
onmessage里调window.print(),也不要用iframe+contentWindow.print() - 插件执行完成后会主动推
{"status":"completeSuccess","id":"xxx"},这才是你更新 UI 的时机
重连与指令幂等性最容易被忽略
插件进程可能被用户手动关闭、系统更新杀掉,或网络抖动断连——此时仅靠前端重连不够,指令还必须能重发且不重复打印。
- 监听
onclose后用指数退避重连(1s → 2s → 4s),不要立即重试 - 每条打印指令带唯一
id(推荐crypto.randomUUID()),插件端按id去重 - 前端发完指令后启动 10 秒定时器,超时未收
completeSuccess就标记为“待重试”,下次重连后补发 - 别依赖
onopen立即发指令——有些插件握手完成需要几百毫秒,建议加setTimeout延迟 300ms
真正的难点不在连上 WebSocket,而在于让每条指令在断连、重连、插件重启、用户切换打印机等混乱状态下,仍能准确抵达、执行、反馈。插件不是黑盒,它的日志输出(通常在 %APPDATA%/WeChatShopPrinter/logs/ 或 ~/Library/Logs/)才是调试第一现场。










