优化 WebSocket 实现单例连接用于打印【待测试 】

class PrinterWebSocket {
  constructor(url) {
    if (PrinterWebSocket.instance) {
      return PrinterWebSocket.instance;
    }
    
    this.url = url;
    this.socket = null;
    this.queue = []; // 打印任务队列
    this.isConnecting = false;
    this.retryCount = 0;
    this.maxRetry = 3;
    
    PrinterWebSocket.instance = this;
    this.connect();
  }

  connect() {
    if (this.isConnecting || this.socket) return;
    
    this.isConnecting = true;
    this.socket = new WebSocket(this.url);
    
    this.socket.onopen = () => {
      console.log('WebSocket连接已建立');
      this.isConnecting = false;
      this.retryCount = 0;
      this.processQueue();
    };
    
    this.socket.onmessage = (event) => {
      console.log('收到打印响应:', event.data);
      // 处理打印响应
    };
    
    this.socket.onclose = () => {
      console.log('WebSocket连接关闭');
      this.socket = null;
      if (this.retryCount < this.maxRetry) {
        this.retryCount++;
        setTimeout(() => this.connect(), 1000 * this.retryCount);
      }
    };
    
    this.socket.onerror = (error) => {
      console.error('WebSocket错误:', error);
      this.socket = null;
      this.isConnecting = false;
    };
  }

  print(data) {
    if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
      console.log('连接未就绪,加入打印队列');
      this.queue.push(data);
      if (!this.isConnecting) {
        this.connect();
      }
      return;
    }
    
    try {
      this.socket.send(JSON.stringify(data));
      console.log('打印指令已发送');
    } catch (error) {
      console.error('发送打印指令失败:', error);
      this.queue.push(data);
      this.socket = null;
      this.connect();
    }
  }

  processQueue() {
    while (this.queue.length > 0 && this.socket?.readyState === WebSocket.OPEN) {
      const data = this.queue.shift();
      this.socket.send(JSON.stringify(data));
    }
  }

  static getInstance(url) {
    if (!PrinterWebSocket.instance) {
      PrinterWebSocket.instance = new PrinterWebSocket(url);
    }
    return PrinterWebSocket.instance;
  }
}

使用方法:

// 初始化单例(通常在应用启动时)
const printer = PrinterWebSocket.getInstance('ws://your-print-server/ws');

// 打印时直接使用
function handlePrint() {
  const printData = {
    type: 'print',
    content: '要打印的内容',
    copies: 1
  };
  
  printer.print(printData);
}

// 页面按钮点击事件
document.getElementById('print-btn').addEventListener('click', handlePrint);

 

优化建议

  1. 心跳机制:添加心跳保持连接活跃

// 在构造函数中添加
this.heartbeatInterval = setInterval(() => {if (this.socket?.readyState === WebSocket.OPEN) {this.socket.send(JSON.stringify({ type: 'heartbeat' }));}
}, 30000);

  1. 连接状态通知:提供连接状态变更回调

// 添加状态监听
this.onStatusChange = null;// 状态变更时
const notifyStatus = (status) => {if (this.onStatusChange) {this.onStatusChange(status);}
};// 在onopen/onclose/onerror中调用notifyStatus

  1. 打印结果回调:支持打印结果返回

print(data, callback) {const task = { data, callback };this.queue.push(task);// ...其余逻辑
}// 在onmessage中处理响应时调用callback

这种实现方式避免了每次打印都创建新连接,提高了效率并减少了服务器压力,同时保证了打印任务的可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87824.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud Alibaba/Spring Boot整合华为云存储实例(REST API方式)

一个小作业&#xff0c;初次尝试华为云存储&#xff0c;一点分享 原项目采用Spring Cloud Alibaba微服务技术、Spring Boot框架技术、VueJS前端框架开发技术&#xff0c;nacos注册中心&#xff0c;数据库为mysql 下面看一下没有运用云存储的原项目&#xff08;可跳过&#xf…

Petalinux工程如何离线编译

目录 一.下载离线包 1.1 共享状态缓存包&#xff1a;sstate-cache 1.1.1 进入官网打开Petalinux工具网页 1.1.2 找到相应的Petalinux版本 1.1.3 根据平台下载 1.2 下载downloads源码包 1.3 open_components源码包 二.解压 2.1 sstate-cache 2.2 downloads源码包 2.3…

w446数字化农家乐管理平台的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

AWS WebRTC:通过shell分析viewer端日志文件

在并发过程中,每个viewer会产生一个对应的日志文件,日志文件名为: viewer_channel_index_20250626_030943_145.logviewer端日志比master端日志文件数量多,比例大概是5:1,有1个master就会有5个viewer,每个viewer对应一个日志文件。 我要统计的是从启动viewer到出第一帧视…

时间转换——借助时间模块time

两种时间戳类型 例如s11704879917000 1、13位的时间戳&#xff1a;单位&#xff08;毫秒&#xff09; &#xff08;1&#xff09;毫秒变成秒&#xff0c;1s1000ms&#xff0c;s1/1000&#xff08;秒&#xff09; &#xff08;2&#xff09;加载时间 times time.localtime(…

LabVIEW MathScript薄板热流模拟

热流模拟是热设计关键环节&#xff0c;传统工具精准但开发周期长&#xff0c;本 VI 利用 LabVIEW 优势&#xff0c;面向工程师快速验证需求&#xff0c;在初步方案迭代、教学演示等场景更具效率&#xff0c;为热分析提供轻量化替代路径&#xff0c;后续可结合专业工具&#xff…

为什么大语言模型训练和推理中越来越多地使用 bfloat16?

随着大语言模型&#xff08;LLM&#xff09;的参数规模从几十亿&#xff08;B&#xff09;飙升到千亿&#xff08;T&#xff09;级别&#xff0c;模型的训练与推理效率变得尤为关键。为了在保证精度的同时节省显存、加快运算&#xff0c;混合精度训练&#xff08;Mixed Precisi…

暴力破解漏洞与命令执行漏洞

在当今的互联网世界中&#xff0c;网络安全威胁无处不在。对于Java后端开发者而言&#xff0c;了解常见的Web漏洞及其防护措施至关重要。本文将探讨两种常见的安全漏洞&#xff1a;暴力破解漏洞&#xff08;Brute Force&#xff09;和命令执行漏洞&#xff08;Command Injectio…

HDFS Java API 开发指南:从基础操作到高级应用

HDFS (Hadoop Distributed File System) 作为大数据生态的核心存储系统&#xff0c;提供了分布式、高容错、高吞吐量的数据存储能力。通过 Java API 操作 HDFS 是开发大数据应用的基础技能。本文将基于你的笔记&#xff0c;详细解析 HDFS Java API 的使用方法&#xff0c;并提供…

区块链技术核心组件及应用架构的全面解析

区块链技术是一套融合密码学、分布式系统与经济激励的复合型技术体系&#xff0c;以下是其核心组件及应用架构的全面解析&#xff1a;一、区块链核心技术栈 1. 分布式账本技术&#xff08;DLT&#xff09; 核心原理&#xff1a;多节点共同维护不可篡改的数据链数据结构&#xf…

golang 协程 如何中断和恢复

Go语言通知协程退出(取消)的几种方式 - 知乎 GoLang之goroutine底层系列二(goroutine的创建、让出、恢复)_golang goroutine-CSDN博客 在 Go 语言中&#xff0c;协程&#xff08;也称为 goroutine&#xff09;是通过 go 关键字启动的轻量级线程。由于 goroutine 的调度是由 Go…

ARMv8 创建3级页表示例

最近在研究arm v8页表创建过程&#xff0c;顺带做了一个如下形式的页表&#xff0c; // level 1 table, 4 entries: // 0000 0000 - 3FFF FFFF, 1GB block, DDR // 4000 0000 - 7FFF FFFF, 1GB block, DDR // 8000 0000 - BFFF FFFF, 1GB block, DDR // C000 0000 - FFFF FFFF…

迁港战平 精神可胜国足

迁港战平可胜国足 江苏省城市足球联赛第6轮&#xff0c;宿迁队主场迎战连云港队。比赛中&#xff0c;宿迁队由张栋和高驰各入一球&#xff0c;连云港队则凭借穆家鑫与李团杰的进球连扳两城。最终双方以2比2握手言和。 第38分钟&#xff0c;张栋角球进攻中无人盯防推射破门&…

408第三季part2 - 计算机网络 - ip分布首部格式与分片

理解 好好看一下这个图 每行是4B&#xff0c;首部也不一定是20B&#xff0c;还有可选字段&#xff0c;可以变的更大 然后我们先看一下概念 然后这个生存时间每路过一个路由器就会扣1滴血 比如一开始是13&#xff0c;经过r1r2r3到B会变成10 但如果是2&#xff0c;经过第二个路…

详解String类不可变的底层原理

String类 String的基本特性 不可变性: String 对象一旦创建就不能被修改&#xff0c;所有看似修改的操作实际上都是创建新的 String 对象final类: String 类被声明为 final&#xff0c;不能被继承基于字符数组: 内部使用final char value[]存储字符数据(Java9以后改为byte[] …

GIT: 一个用于视觉与语言的生成式图像到文本转换 Transformer

摘要 在本文中&#xff0c;我们设计并训练了一个生成式图像到文本转换 Transformer——GIT&#xff0c;以统一视觉-语言任务&#xff0c;如图像/视频字幕生成和问答。虽然生成式模型在预训练和微调之间提供了一致的网络架构&#xff0c;但现有工作通常包含复杂的结构&#xff…

20250706-9-Docker快速入门(下)-Docker在线答疑_笔记

一、Kubernetes核心概念与集群搭建 1. 在线答疑 &#xfeff; 1&#xff09;答疑Docker需要掌握到什么程度 学习目标&#xff1a;达到入门水平即可&#xff0c;重点掌握第一章Docker入门视频内容学习建议&#xff1a;预习时间约3-4小时&#xff0c;建议吸收视频内容的80%学…

Node.js-http模块

HTTP 协议 概念 HTTP&#xff08;hypertext transport protocol&#xff09;协议&#xff1b;中文叫超文本传输协议,是一种基于TCP/IP的应用层通信协议这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。协议中主要规定了两个方面的内容 客户端&#xff1a;用来…

Java JDBC的初步了解

文章目录 基本流程注册驱动的两种方法DriverManagerDriverManager 的核心作用核心原理自动注册驱动的机制关键方法 示例代码: 连接Mysql数据库StatementPreparedStatement JDBC全称Java DataBase Connectivity。 定义: JDBC 是 Java 语言中用于连接和执行 SQL 操作的标准接口。…

[netty5: ChunkedInput ChunkedWriteHandler]-源码分析

ChunkedInput ChunkedInput<B> 是 Netty 中用于按块读取不定长数据流的接口&#xff0c;常配合 ChunkedWriteHandler 实现流式写入&#xff0c;支持如文件、流、HTTP 和 WebSocket 等多种数据源。 实现类简要说明ChunkedFile用于将常规文件按块传输&#xff08;使用传统…