SockJS实践:即时通信关键点

2024-04-01 05:18

本文主要是介绍SockJS实践:即时通信关键点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果说之前的 Socket.IO打造基础聊天室 让我明白了聊天室的原理,知道了如何实现群聊(广播)和私聊(单播)等,那么对于 SockJS 的实践让我更加了解了websocket,因为 Sock.IO 是自己封装的接口,而 SockJS 则使用了跟 websocket 几乎相同的 API。

01 SockJS简介

  • 与 Socket.io 不同,在传输方式的选择方面,SockJS 会优先采用 websocket,然后再自动降级;
  • 其 API 几乎与 websocket API 的使用方式相同;
  • 兼容跨浏览器,支持跨域。

02 即时通信关键点

(1)心跳检测(业务层面)

(ws自身有心跳,但是如果有一些业务层面的需求,就需要自己实现心跳)

ws建立成功时便进行 心跳请求(每隔一段时间发送一个 PING),同时初始化 超时重连。如果在达到心跳规定次数后仍没有返回 PONG,则判定心跳超时,前端主动关闭ws,触发 ws重连

如果期间收到了 PONG,则重新初始化超时重连。

【注意】:ws重连的时候,要清空之前的心跳定时器。

(2)关闭连接的3种情况:

  • 心跳超时(连接层不断)的情况,则前端可主动关闭 ws;
  • 连接未建立成功(如TCP连接断掉),ws 自动关闭;
  • 服务端关闭(如多端剔除),这是要防止前端进行重连。

正常关闭(如心跳超时)

连接失败(如TCP层没有连接成功)

【注意】:锁屏情况下,js 会停止工作,这时,ws 会自动关闭,当屏幕唤醒时,通过触发 onclose 事件,ws 又会进行重连。在某些特殊业务场景下,需要注意下这种情况。

(3)websocket 自动重连

无论是前端主动关闭 ws,还是ws自动关闭,都会触发 onclose 事件,可在其中进行重连。如果达到了重连次数或者后端返回了不可进行重连的标志码,则不进行重连。

【实现思路】:

var CONNECT_COUNT = 3;
var sockjs;
var sockjs_url = '/chat/sjs/';
var isClose = false;
var connectCount = 1;new_conn = function() {    sockjs = new SockJS(sockjs_url);sockjs.onopen = function() {connectCount = 1;   // 重置重连次数this.checkHeartBeat();  // 心跳检测}sockjs.onmessage = function(e) {var data = JSON.parse(e.data);// handleMessage(data);};sockjs.onclose = function(e) {// 已经关闭的情况,不重连if (isClose) { return;}// 小于重连次数if (connectCount < CONNECT_COUNT) {setTimeout(function() {new_conn();}, (Math.random() * 3 + 1 )* 1000);   } else {isClose = true;}};
}

(4)sockJS session_id:可用于多端剔除

url格式类似于:/resource/<server_number>/<session_id>/transport

请求URL

每个 sockJS 都有 session_id,可通过它来判断是否同一个用户建立了2个ws,如多端登录的情况下,可用于进行多端剔除。

var socket = new SockJS('/mqClient');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {console.log(socket._transport.url); //it contains ws://localhost:8080/mqClient/039/byxby3jv/websocket//sessionId is byxby3jv});

The SockJS constructor has an option parameter and there you can pass a custom session id generator as a function:

let sessionId = utils.random_string(8);
let socket = new SockJS('/socket', [], {sessionId: () => {return sessionId}});

 

03 sockJS readyState(暂时没用到。。)

【sockjs-client 部分源码】:

SockJS.CONNECTING = 0;
SockJS.OPEN = 1;
SockJS.CLOSING = 2;
SockJS.CLOSED = 3;
SockJS.prototype.close = function(code, reason) {// Step 1if (code && !userSetCode(code)) {throw new Error('InvalidAccessError: Invalid code');}// Step 2.4 states the max is 123 bytes, but we are just checking lengthif (reason && reason.length > 123) {throw new SyntaxError('reason argument has an invalid length');}// Step 3.1if (this.readyState === SockJS.CLOSING || this.readyState === SockJS.CLOSED) {return;}// TODO look at docs to determine how to set thisvar wasClean = true;this._close(code || 1000, reason || 'Normal closure', wasClean);
};

参考

  • 学习WebSocket协议—从顶层到底层的实现原理(修订版)
  • websocket RFC - EN
  • websocket RFC(翻译)
  • sockjs chat room
  • What happens if sockJS gets disconnected?

 

这篇关于SockJS实践:即时通信关键点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866289

相关文章

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

springboot依靠security实现digest认证的实践

《springboot依靠security实现digest认证的实践》HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因... 目录概述参数Demopom.XML依赖Digest1Application.JavaMyPasswo

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

Java 结构化并发Structured Concurrency实践举例

《Java结构化并发StructuredConcurrency实践举例》Java21结构化并发通过作用域和任务句柄统一管理并发生命周期,解决线程泄漏与任务追踪问题,提升代码安全性和可观测性,其核心... 目录一、结构化并发的核心概念与设计目标二、结构化并发的核心组件(一)作用域(Scopes)(二)任务句柄

Java中的Schema校验技术与实践示例详解

《Java中的Schema校验技术与实践示例详解》本主题详细介绍了在Java环境下进行XMLSchema和JSONSchema校验的方法,包括使用JAXP、JAXB以及专门的JSON校验库等技术,本文... 目录1. XML和jsON的Schema校验概念1.1 XML和JSON校验的必要性1.2 Sche

SpringBoot集成WebService(wsdl)实践

《SpringBoot集成WebService(wsdl)实践》文章介绍了SpringBoot项目中通过缓存IWebService接口实现类的泛型入参类型,减少反射调用提升性能的实现方案,包含依赖配置... 目录pom.XML创建入口ApplicationContextUtils.JavaJacksonUt

MyCat分库分表的项目实践

《MyCat分库分表的项目实践》分库分表解决大数据量和高并发性能瓶颈,MyCat作为中间件支持分片、读写分离与事务处理,本文就来介绍一下MyCat分库分表的实践,感兴趣的可以了解一下... 目录一、为什么要分库分表?二、分库分表的常见方案三、MyCat简介四、MyCat分库分表深度解析1. 架构原理2. 分

Java 中的 equals 和 hashCode 方法关系与正确重写实践案例

《Java中的equals和hashCode方法关系与正确重写实践案例》在Java中,equals和hashCode方法是Object类的核心方法,广泛用于对象比较和哈希集合(如HashMa... 目录一、背景与需求分析1.1 equals 和 hashCode 的背景1.2 需求分析1.3 技术挑战1.4

k8s搭建nfs共享存储实践

《k8s搭建nfs共享存储实践》本文介绍NFS服务端搭建与客户端配置,涵盖安装工具、目录设置及服务启动,随后讲解K8S中NFS动态存储部署,包括创建命名空间、ServiceAccount、RBAC权限... 目录1. NFS搭建1.1 部署NFS服务端1.1.1 下载nfs-utils和rpcbind1.1