Java开发中Websocket的技术选型参考
1. 前言
Websocket是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据,当然也支持客户端发送数据到服务端。通常用来社交聊天、弹幕、多玩家游戏、协同编辑、股票基金实时报价、资讯自动更新等场景,那么今天就简单聊一下在 Java 开发中对Websocket的技术选型。
技术选型是结合自身业务选择最适合的技术方案,并不存在褒贬。
2. 常用的 Websocket 技术
2.1 Java Websocket 规范
这是JavaEE提供的规范,在包javax.websocket
下,包含客户端 API 和服务端 API,服务端 API 完全依赖于客户端 API,只是在其基础上添加了一些功能,所以只需要导入服务端依赖即可。 具体实现需要 Web 容器、JavaEE 服务器或者框架提供。我们常用的 Web 容器Tomcat、Undertow等都支持。
优点:集成起来简单,原生的Java支持。
缺点:和 Web 服务器等共享容器耦合度高,广播、组播需要自行控制。并发量较低,调优麻烦,存在兼容性问题。
2.2 SockJS
SockJS是一个浏览器JavaScript库,对Websocket进行了抽象。SockJS为您提供了一个一致的,跨浏览器的Javascript API,该 API 在浏览器和 Web 服务器之间创建了低延迟,全双工,跨域的通信通道。SockJS尝试首先使用本机WebSockets。如果失败了,它将尝试其它各种特定于浏览器的传输协议,例如xhr-streaming、Server sent events 以及长轮询等。通常也会配合STOMP(面向消息的简单文本协议)来简化其使用。其实Spring 的Websocket组件中采用的就是此协议。
优点:社区活跃,技术成熟,协议栈丰富,有全套 Spring 解决方案,兼容性强,另外可以结合发布订阅模式。
缺点:需要对 SockJS 和 STOMP 进行学习,断线重连、心跳检测、二进制支持不好。
2.3 Socket.IO
Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用,但是它提供基于Netty的服务端实现以及客户端实现,同时支持Websocket和长轮询。除了Websocket的常用场景外,我们可以通过该组件实现安卓和IOS的消息推送。
优点:性能良好,支持广播、组播,断线重连、心跳检测、二进制。支持安卓和 IOS 平台。社区活跃。
缺点:需要自行封装同 Spring 的集成,服务端并非社区维护,资源消耗大。
2.4 ReactiveStream
一些反应流规范和框架也对Websocket进行了实现。Spring Webflux和RSocket就是其中的代表,目前官方已经放出了一些相关的 DEMO。
优点:高吞吐量、高性能。
缺点:技术比较新、学习资料少。
3. 总结
这里无法给出也不可能哪种更好的结论。如果业务量非常少而且非常急迫的话第一种可以尝试一下。SockJS和Socket.IO的争论点在于性能上后者要好一些,当然资源也消耗大,对移动端的推送功能支持更好一些。在Spring整合上以及全套解决方案上SockJS更具优势。如果追求高性能、高吞吐量的Websocket那么无疑反应式更加合适,但是学习成本也相对较高。其它小众的技术这里不做评测,如果你有比较好的方案可留言讨论。
附:性能基准测试
以下是国外某论文在 2020 年对原生Websocket、SockJS、Socket.IO进行的性能测试的一些关键指标。
随着客户端的增多创建连接的耗时
随着客户端连接增多接收消息的平均时间
接收一条消息所消耗的连接数和重组的TCP分段数
服务端内存占用趋势
- HDU 1728 逃离迷宫(DFS经典题,比赛手残写废题)
- 洛谷 P1219 八皇后【经典DFS,温习搜索】
- KVM基于内核的虚拟机概念理解与客户机浅析
- 洛谷 P1972 [SDOI2009]HH的项链【莫队算法学习】
- BZOJ 2257: [Jsoi2009]瓶子和燃料【数论:裴蜀定理】
- 在 EF 5 中跟踪SQL和缓存数据
- hihoCoder #1015 : KMP算法【KMP裸题,板子】
- 对X86汇编的理解与入门
- BZOJ 2748: [HAOI2012]音量调节【二维dp,枚举】
- POJ 3264 Balanced Lineup【线段树区间查询求最大值和最小值】
- HDU 2289 Cup【高精度,二分】
- BZOJ 1083: [SCOI2005]繁忙的都市【Kruscal最小生成树裸题】
- [快学Python3]二分查找[策略优化版本]
- 微服务与SOA架构(4)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 深入探究JVM之垃圾回收算法实现细节
- 深入探究JVM之类加载与双亲委派机制
- 深入探究JVM之方法调用及Lambda表达式实现原理
- synchronized的实现原理——对象头解密
- Golang 汇编入门知识总结
- C语言小笔记(1)
- 这一次搞懂Spring的XML解析原理
- 这一次搞懂Spring自定义标签以及注解解析原理
- 这一次搞懂Spring的Bean实例化原理
- 单片机入门学习十三 STM32单片机学习十 通用定时器
- Spring IOC原理补充(循环依赖、Bean作用域等)
- 这一次搞懂Spring代理创建及AOP链式调用过程
- 这一次搞懂Spring事务注解的解析
- 这一次搞懂Spring事务是如何传播的
- 这一次搞懂SpringMVC原理