Spring 框架从 4.0 版开始支持 webSocket, 先简单介绍 WebSocket 协议(详细介绍参见 "WebSocket 协议中文版"https://www.cnblogs.com/xxkj/p/14273710.html).
1,WebSocket 协议介绍
WebSocket 协议是 RFC-6455 规范定义的一个 Web 领域的重要的功能: 全双工, 即客户端和服务器之间的双向通信. 它是一个令人兴奋的功能, 业界在此领域上已经探索很久, 使用的技术包括 Java Applet,XMLHttpRequest,Adobe Flash,ActiveXObject, 各种 Comet 技术, 服务器端的发送事件等.
需要理解一点, 在使用 WebSocket 协议前, 需要先使用 HTTP 协议用于构建最初的握手. 这依赖于一个机制 -- 建立 HTTP, 请求协议升级(或叫协议转换). 当服务器同意后, 它会响应 HTTP 状态码 101, 表示同意切换协议. 假设通过 TCP 套接字成功握手, HTTP 协议升级请求通过, 那么客户端和服务器端都可以彼此互发消息.
Spring 框架 4.0 以上版本引入了一个新模块, 即 spring-websocket 模块. 它对 WebSocket 通信提供了支持. 它兼容 Java WebSocket API 规范 JSR-356, 同时提供了额外的功能.
2,WebSocket 的降级选项
浏览器对 WebSocket 的支持并不快, IE 浏览器是第 10 版才开始支持的. 此外, 一些代理工具也会限制 WebSocket 通信. 因此, 即使是现在要开发 WebSocket 应用, 降级选项是必不可少的, 以便在不支持的场景使用模拟 WebSocket API 的工作方式. Spring 框架提供了这种透明的降级方案 -- 使用 SockJS 协议. 此方案可以通过配置来自动切换, 无需修改应用程序的代码.
SockJS 是 WebSocket 技术的一种模拟, 在表面上, 它尽可能对应 WebSocket API, 但是在底层它非常智能. SockJS 会优先选用 WebSocket, 但是如果 WebSocket 不可用的话, 它将会从如下的方案中挑选最优的可行方案: XHR 流, XDR 流, iFrame 事件源, iFrame HTML 文件, XHR 轮询, XDR 轮询, iFrame XHR 轮询, JSONP 轮询.
3, 消息通信架构
使用 WebSocket 除了开发方面的挑战外, 还有一个难点在于设计上的考虑.
目前 REST 架构是一个广泛接受, 易于理解, 适合构建现代 Web 应用的架构. REST 架构依赖于很多 URL 和几个 HTTP 方法, 使用了链接, 保持无状态等原则.
相比之下 WebSocket 应用可能只使用一个 URL 用于最初的 HTTP 握手. 随后所有的消息都共享此 TCP 连接, 消息在此连接上双向流动. 这一点可见, 它与 REST 架构是完全不同的, 是异步的, 事件驱动的, 消息传递的架构. WebSocket 架构与传统的消息传输方案 (如 JMS,AMQP) 比较相似.
Spring 框架 4.0 引入了一个新模块 --spring-messaging 模块, 它包含了很多来自于 Spring Integration 项目中的概念抽象, 比如: Message 消息, 消息频道 MessageChannel, 消息句柄 MessageHandler 等. 此模块还包括了一套注释, 可以把消息映射到方法上, 与 Spring MVC 基于注释的编程模型相似.
4,WebSocket 支持子协议
WebSocket 只是一个消息传递的体系结构, 它没有指定任何特定的消息传递协议. 它是一个 TCP 协议之上的超薄层, 可以把字节流转换成消息流(文本或二进制). 随后由应用程序来解释消息.
与 HTTP 协议不同, WebSocket 协议只是一个应用级的协议, 它非常简单, 并不能理解传入的消息, 也不能对消息进行路由或处理. 因此 WebSocket 协议是应用级协议的底层, 其上需要一个框架来理解和处理消息.
出于这个原因, WebSocket RFC 定义了子协议的使用. 在握手过程中, 客户端和服务器端可以使用 Header 部分的 Sec-WebSocket-Protocol 来协商使用的子协议 -- 也即使用更高级的应用级协议. 子协议的使用不是必须的, 但即使不使用子协议, 应用程序仍然需要选择一个消息格式 -- 让客户端和服务器相互可以理解的格式. 这种格式可以自定义, 或特定于框架, 或使用标准的消息传递协议.
Spring 框架提供了对使用 STOMP 子协议的支持.
STOMP,Streaming Text Orientated Message Protocol, 流文本定向消息协议. STOMP 是一个简单的消息传递协议, 是一种为 MOM(Message Oriented Middleware, 面向消息的中间件)设计的简单文本协议.
STOMP 提供了一个可互操作的连接格式, 允许 STOMP 客户端与任意 STOMP 消息代理 (Broker) 进行交互, 类似于 OpenWire 协议(一种二进制协议).
5,WebSocket 和 HTTP 的区别
WebSocket 建立在 TCP 之上, 同 HTTP 一样通过 TCP 来传输数据, 它和 HTTP 不同之处有:
(1)HTTP 和 WebSocket 是两种不同的协议, 但是 HTTP 负责了建立 WebSocket 的连接.
(2)HTTP 请求以 http:// 或 https:// 开始, WebSocket 请求一般以 ws:// 或 wss:// 开始.
(3)所有浏览器都支持 HTTP 协议, WebSocket 可以会遇到不支持的浏览器(可通过 SockJS 解决).
(4)HTTP 长连接中, 每次数据交换除了真正的数据部分外, 服务器和客户端还要大量交换 HTTP header, 信息交换效率很低. Websocket 协议通过第一个 request 建立了 TCP 连接之后, 之后交换的数据都不需要发送 HTTP header 就能交换数据.
(5)WebSocket 是一种双向通信协议, 在建立连接后, WebSocket 服务器和 Browser/ Client Agent 都能主动的向对方发送或接收数据, 就像 Socket 一样.
(6)WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接, 连接成功后才能相互通信.
6,WebSocket 使用场景
在 Web 应用中, 客户端和服务器端需要以较高频率和较低延迟来交换事件时, 适合用 WebSocket. 因此 WebSocket 适合财经, 游戏, 协作等应用场景.
对于其他应用场景则未必适合. 例如, 某个新闻订阅需要显示突发新闻, 使用间隔几分钟的长轮询也是可以的, 这里的延迟可以接受.
即使在要求低延迟的应用场景, 如果传输的消息数很低(比如监测网络故障的场景), 那么应该考虑使用长轮询技术.
而只有在低延迟和高频消息通信的场景下, 选用 WebSocket 协议才是非常适合的. 即使是这样的应用场景, 仍然存在是选择 WebSocket 通信还是选择 REST HTTP 通信.
答案是会根据应用程序的需求而定. 但是, 也可能同时使用这两种技术, 把需要频繁交换的数据放到 WebSocket 中实现, 而把 REST API 作为过程性的业务的实现技术. 另外, 当 REST API 的调用中需要把某个信息广播给多个客户端时, 也可以通过 WebSocket 连接来实现.
下面基于的 Spring 版本为 5.2.4.BUILD-SNAPSHOT 源码, 对 websocket 模块中包含的类和接口进行分析.
一, Web/socket/
1.1 WebSocketMessage: 接口, 可以在 WebSocket 连接上处理或发送的消息.
1.2 AbstractWebSocketMessage: 抽象类, 可以在 WebSocket 连接上处理或发送的消息.
1.3 BinaryMessage: 二进制 WebSocket 消息.
1.4 TextMessage: 文本 WebSocket 消息.
一个帧有一个相应的类型. 属于相同消息的每一帧包含相同类型的数据. 从广义上讲, 有文本数据类型 (它被解释为 UTF-8[RFC3629] 文本), 二进制数据类型(它的解释是留给应用), 和控制帧类型(它不包含用于应用的数据, 而是协议级的信号, 例如应关闭连接的信号).
1.5 PingMessage: 一个 WebSocket ping 消息.
Ping 帧包含 0x9 操作码.
Ping 帧可以包含 "应用数据".
当接收到一个 ping 帧时, 一个端点必须在响应中发送一个 Pong 帧, 除非它早已接收到一个关闭帧. 它应该尽可能快地以 Pong 帧响应.
一个端点可以在连接建立之后并在连接关闭之前的任何时候发送一个 Ping 帧.
一个 Ping 可以充当一个 keepalive, 也可以作为验证远程端点仍可响应的手段.
Ping 帧是控制帧的一种. 控制帧由操作码确定, 其中操作码最重要的位是 1. 当前定义的用于控制帧的操作码包括 0x8 (Close), 0x9 (Ping), 和 0xA (Pong). 操作码 0xB-0xF 保留用于未来尚未定义的控制帧. 控制帧用于传达有关 WebSocket 的状态. 控制帧可以插入到分片消息的中间. 所有的控制帧必须有一个 125 字节的负载长度或者更少, 必须不被分段.
1.6 PongMessage: 一个 WebSocket pong 消息.
Pong 帧包含一个 0xA 操作码.
一个 Pong 帧用来回应一个 Ping 帧时, 必须包含一份在接收到的 Ping 帧的消息体中完全相同的 "应用数据".
如果端点接收到一个 Ping 帧但是对于前一个 Ping 帧还没有返回相应的 Pong 帧, 端点可以选择仅为最近处理的 Ping 帧发送一个 Pong 帧.
一个 Pong 帧可以自发的进行发送, 充当单向的心跳. 接收到一个自发的 Pong 帧时不需要回应一个 Pong 帧.
1.7 SubProtocolCapable:WebSocket 处理器的接口, 支持定义在 RFC 6455 中的子协议.
客户端可能通过包含 | Sec-WebSocket-Protocol | 字段在它的握手中使用一个特定的子协议请求服务器. 如果它被指定, 服务器需要在它的响应中包含同样的字段和一个选择的子协议值用于建立连接.
1.8 CloseStatus: 表示一个 WebSocket 连接关闭的原因. 状态时一个在 1000 到 4999(包括)之间的一个整数数字. 每一个状态码都必须有唯一的含义.
1000: 表示正常关闭, 意思是建议的连接已经完成了.
1001: 表示端点 "离开", 例如服务器关闭或浏览器导航到其他页面.
1002: 表示端点因为协议错误而终止连接.
1003: 表示端点由于它收到了不能接收的数据类型 (例如, 端点仅理解文本数据, 但接收到了二进制消息) 而终止连接.
1004: 保留. 可能在将来定义某具体的含义.
1005: 是一个保留值, 且不能由端点在关闭控制帧中设置此状态码. 它被指定用在期待一个用于表示没有状态码是实际存在的状态码的应用中.
1006: 是一个保留值, 且不能由端点在关闭控制帧中设置此状态码. 它被指定用在期待一个用于表示连接异常关闭的状态码的应用中.
1007: 表示端点因为消息中接收到的数据是不符合消息类型而终止连接 (比如, 文本消息中存在非 UTF-8 [RFC3629] 数据).
1008: 表示端点因为接收到的消息违反其策略而终止连接. 这是一个当没有其它合适状态码 (例如 1003 或 1009) 或如果需要隐藏策略的具体细节时能被返回的通用状态码.
1009: 表示端点因接收到的消息对它的处理来说太大而终止连接.
1010: 表示端点 (客户端) 因为它期望服务器协商一个或多个扩展, 但服务器没有在 WebSocket 握手响应消息中返回它们而终止连接. 所需要的扩展列表应该出现在关闭帧的 / reason / 部分. 注意, 这个状态码不能被服务器端使用, 因为它可以使 WebSocket 握手失败.
1011: 表示服务器端因为遇到了一个不期望的情况使它无法满足请求而终止连接.
1015: 是一个保留值, 且不能由端点在关闭帧中被设置为状态码. 它被指定用在期待一个用于表示连接由于执行 TLS 握手失败而关闭的状态码的应用中(比如, 服务器证书不能验证).
1.9 WebSocketExtension: 表示一个在 RFC 6455 中定义的 WebSocket 扩展. 扩展提供了一种机制来实现选择性加入的附加协议特性.
WebSocket 客户端可以请求 RFC6455 规范的扩展, 且 WebSocket 服务器可以接受一些或所有客户端请求的扩展. 服务器不必响应不是客户端请求的任何扩展. 如果扩展参数包含在客户端和服务器之间的协商中, 这些参数必须按照参数应用到的扩展规范来选择.
1.10 WebSocketHandler:WebSocket 消息及其生命周期中的事件处理器. 实现该接口的类最好也同时对本地的异常进行处理, 如可以对异常进行记录, 使用 1011(表示服务器端因为遇到了一个不期望的情况使它无法满足请求而终止连接)状态码关闭会话.
1.11 WebSocketHttpHeaders: 继承自 org.springframework.http.HttpHeaders, 增加对在 RFC 6455 WebSocket 规范中定义的 HTTP 头部的支持.
头字段名: Sec-WebSocket-Key
相关信息: 该头字段仅用于 WebSocket 打开阶段握手.
|Sec-WebSocket-Key | 头字段用于 WebSocket 打开阶段握手. 它从客户端发送到服务器, 提供部分信息用于服务器检验它收到了一个有效的 WebSocket 握手. 这有助于确保服务器不接收正被滥用来发送数据给毫不知情的 WebSocket 服务器的非 WebSocket 客户端的连接(例如 HTTP 客户端).
|Sec-WebSocket-Key | 头字段在一个 HTTP 请求中不能出现多于一个.
头字段名: Sec-WebSocket-Extensions
相关信息: 该头字段仅用于 WebSocket 打开阶段握手.
|Sec-WebSocket-Extensions | 头字段用于 WebSocket 打开阶段握手. 它最初是从客户端发送到服务器, 随后从服务器端发送到客户端, 用来达成在整个连接阶段的一组协议级扩展.
|Sec-WebSocket-Extensions | 头字段在 HTTP 请求中可以出现多次(逻辑上等价于单个 | Sec-WebSocket-Extensions | 头字段包含的所有值). 但是,|Sec-WebSocket-Extensions | 头字段在一个 HTTP 响应中必须不出现多于一次.
头字段名: Sec-WebSocket-Accept
相关信息: 该头字段仅用于 WebSocket 打开阶段握手.
|Sec-WebSocket-Accept | 头字段用于 WebSocket 打开阶段握手. 它从服务器发送到客户端来确定服务器愿意启动 WebSocket 连接.
|Sec-WebSocket-Accept | 头在一个 HTTP 响应中必须不出现多于一次.
头字段名: Sec-WebSocket-Protocol
相关信息: 该头字段仅用于 WebSocket 打开阶段握手.
|Sec-WebSocket-Protocol | 头字段用于 WebSocket 打开阶段握手. 它从客户端发送到服务器端, 并从服务器端发回到客户端来确定连接的子协议. 这使脚本可以选择一个子协议和确定服务器同一服务子协议.
|Sec-WebSocket-Protocol | 头字段在一个 HTTP 请求中可以出现多次(逻辑上等价于 | Sec-WebSocket-Protocol | 头字段包含的所有值). 但是,|Sec-WebSocket-Protocol | 头字段在一个 HTTP 响应必须不出现多于一次.
头字段名: Sec-WebSocket-Version
相关信息: 该头字段仅用于 WebSocket 打开阶段握手.
|Sec-WebSocket-Version | 头字段用于 WebSocket 打开阶段握手. 它从客户端发送到服务器端来指定连接的协议版本. 这能使服务器正确解释打开阶段握手和发送数据的随后数据. 如果服务器不能以安全的方式解释数据则关闭连接. 当从客户端接收到不匹配服务器端理解的版本是, WebSocket 握手错误,|Sec-WebSocket-Version | 头字段也从服务器端发送到客户端. 在这种情况下, 头字段包括服务器端支持的协议版本.
注意: 如果没有期望更高版本号, 必然是向下兼容低版本号.
|Sec-WebSocket-Version | 头字段在一个 HTTP 响应中可以出现多次(逻辑行等价于单个 | Sec-WebSocket-Version | 透过自动包含的所有值). 但是,|Sec-WebSocket-Version | 头字段在 HTTP 请求中必须不出现多于一次.
来自客户端的握手看起来像如下形式:
- GET /chat HTTP/1.1
- Host: server.example.com
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
- Origin: http://example.com
- Sec-WebSocket-Protocol: chat, superchat
- Sec-WebSocket-Version: 13
来自服务器的握手看起来像如下形式:
- HTTP/1.1 101 Switching Protocols
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
- Sec-WebSocket-Protocol: chat
1.12 WebSocketSession: 一个 WebSocket 会话抽象. 允许通过一个 WebSocket 连接发送消息, 也可关闭该连接. 核心函数:
sendMessage(WebSocketMessage<?> message)函数, 用来发送一个 WebSocket 消息, 文本消息或者二进制消息.
close(CloseStatus status)函数, 使用给定的关闭状态码来关闭一个 WebSocket 连接.
二, Web/socket/adapter
2.1 NativeWebSocketSession: 继承自 WebSocketSession 接口, 提供了 getter 方法来暴露本地的 WebSocketSession. 该接口会被 AbstractWebSocketSession 抽象类实现.
2.2 AbstractWebSocketSession:WebSocketSession 接口实现类的抽象基类. 其发送消息函数为 sendMessage(WebSocketMessage<?> message).
Web/socket/adapter/jetty
2.3 JettyWebSocketHandlerAdapter: 适配 Jetty 9 WebSocket API 的 WebSocketHandler.
Jetty 是基于 Java 语言编写的一个开源 servlet 容器, 为 Jsp 和 servlet 提供了运行环境, 可以迅速为一些独立运行的 Java 应用提供网络和 Web 连接.
Jetty 目前正在快速成长为一个优秀的 Servlet 引擎, 但是 Tomcat 的地位还是没办法撼动, 市场份额远远不及 Tomcat 的多.
2.4 JettyWebSocketSession: 使用 Jetty 9.4 WebSocket API 的 WebSocketSession.
2.5 WebSocketToJettyExtensionConfigAdapter: 适配器类, 用于将一个 WebSocketExtension 转换为 Jetty ExtensionConfig.
Web/socket/adapter/standard
2.6 ConvertingEncoderDecoderSupport: 抽象基类, 用于实现一个标准的 javax.websocket.Encoder 和 / 或 javax.websocket.Decoder. 该类通过委托给 Spring 的 ConversionService 实现了编码和解码方法.
默认情况下, 该类使用 "webSocketConversionService" 名字查找在 ApplicationContext 容器中注册的一个 ConversionService.
2.7 StandardToWebSocketExtensionAdapter:WebSocketExtension 的子类, 可以从一个 javax.websocket.Extension 构造.
2.8 StandardWebSocketHandlerAdapter: 适配一个 WebSocketHandler 到基于 Java API 的标准 WebSocket.
2.9 StandardWebSocketSession: 用于基于 Java API 的标准 WebSocket 的 WebSocketSession.
2.10 WebSocketToStandardExtensionAdapter: 适配一个 WebSocketExtension 实例到 javax.websocket.Extension 接口.
三, Web/socket/client
3.1 AbstractWebSocketClient:WebSocketClient 接口实现类的抽象基类.
3.2 ConnectionManagerSupport: 是 WebSocketConnectionManager 的基类.
3.3 WebSocketClient: 负责初始化一个 WebSocket 请求.
3.4 WebSocketConnectionManager: 在指定 uri,WebsocketClient 和 websocketHandler 时通过 start()和 stop()方法连接到 websocket 服务器. 如果 setAutoStartup(boolean)设置为 true,Spring 的 ApplicationContext 容器刷新时会自动连接.
Web/socket/client/jetty
3.5 JettyWebSocketClient: 通过 Jetty WebSocket API, 以编程方式发送 WebSocket 请求到 WebSocket 服务器.
Web/socket/client/standard
3.6 AnnotatedEndpointConnectionManager: 给定了一个 URI, 一个 ClientEndpoint-annotated 端点的 WebSocket 连接管理器, 通过 #start()和 #stop()方法连接到一个 WebSocket 服务器. 如果 setAutoStartup(boolean)设置为 true 时, 当 Spring ApplicationContext 容器刷新的时候这些会自动执行.
3.7 EndpointConnectionManager: 给定了一个 URI, 一个端点的 WebSocket 连接管理器, 通过 #start()和 #stop()方法连接到一个 WebSocket 服务器. 如果 setAutoStartup(boolean)设置为 true 时, 当 Spring ApplicationContext 容器刷新的时候这些会自动执行.
3.8 StandardWebSocketClient: 基于标准的 Java WebSocket API 的 WebSocketClient.
3.9 WebSocketContainerFactoryBean: 一个 FactoryBean, 通过 Spring xml 配置来创建和配置一个 WebSocketContainer. 在 Java 配置中, 忽视该类, 使用 getWebSocketContainer()方法替代.
四, Web/socket/config
4.1 HandlersBeanDefinitionParser: 解析 < websocket:handlers/>命名空间元素. 注册一个 Spring MVC SimpleUrlHanderMapping, 用来将 HTTP WebSocket 握手 (或者 SockJS) 请求映射到 WebSocketHandlers.
SockJS 是一个浏览器上运行的 JavaScript 库, 如果浏览器不支持 WebSocket, 该库可以模拟对 WebSocket 的支持, 实现浏览器和 Web 服务器之间低延迟, 全双工, 跨域的通讯通道.
4.2 MessageBrokerBeanDefinitionParser: 一个 BeanDefinitionParser, 提供 xml 命名空间元素 < websocket:message-broker/>的配置.
4.3 WebSocketMessageBrokerStats: 核心类, 用于聚合 setup 的关键架构组件的内部状态和计数信息, 这些组件 Java 配置带了 @EnableWebSocketMessageBroker,xml 中带了 < websocket:message-broker>.
4.4 WebSocketNamespaceHandler:Spring WebSocket 配置命名空间的 NamespaceHandler.
4.5 WebSocketNamespaceUtils: 提供了功能性函数用于解析通用的 WebSocket xml 命名空间元素.
Web/socket/config/annotation
4.6 AbstractWebSocketHandlerRegistration:WebSocketHandlerRegistrations 接口实现类的抽象基类, 收集所有的配置选项, 但是允许其子类组合真实的 HTTP 请求映射.
4.7 AbstractWebSocketMessageBrokerConfigurer:WebSocketMessageBrokerConfigurer 实现类的抽象基类, 为一些空方法实现了空实现. Spring 5.0 中被废弃, 使用 WebSocketMessageBrokerConfigurer 替代.
4.8 DelegatingWebSocketConfiguration:WebSocketConfigurationSupport 的一个变体, 在 Spring 配置中检测 WebSocketConfigurer 的实现类, 调用他们用于配置 WebSocket 请求处理.
4.9 DelegatingWebSocketMessageBrokerConfiguration: WebSocketMessageBrokerConfigurationSupport 的拓展, 检测 WebSocketMessageBrokerConfigurer 类型的 bean, 并代理这些 bean 允许对 WebSocketMessageBrokerConfigurationSupport 提供的配置进行回调式定制.
4.10 EnableWebSocket: 将该注解加到一个 @configuration 类, 从而配置处理 WebSocket 请求. 一个典型的配置如下:
- @Configuration
- @EnableWebSocket
- public class MyWebSocketConfig {
- }
4.11 EnableWebSocketMessageBroker: 将该注解加到 @Configuration 类, 使 WebSocket 上的 broker-backed 消息使用更高级的消息子协议.
- @Configuration
- @EnableWebSocketMessageBroker
- public class MyWebSocketConfig {
- }
4.12 ServletWebSocketHandlerRegistration: 帮助类, 用于配置包括 SockeJS 回退选项的 WebSocketHandler 请求处理.
4.13 ServletWebSocketHandlerRegistry:WebSocketHandlerRegistry 接口实现类, 使用了 Spring MVC 处理器映射, 用于握手请求.
4.14 SockJsServiceRegistration: 帮助类, 配置 SockJS 回退选项, 用于一个 EnableWebSocket 和 WebSocketConfigurer setup.
4.15 StompEndpointRegistry: 注册 WebSocket 端点上的 STOMP.
STOMP 即 Simple (or Streaming) Text Orientated Messaging Protocol, 简单 (流) 文本定向消息协议, 它提供了一个可互操作的连接格式, 允许 STOMP 客户端与任意 STOMP 消息代理 (Broker) 进行交互. STOMP 协议由于设计简单, 易于开发客户端, 因此在多种语言和多种平台上得到广泛地应用.
4.16 StompWebSocketEndpointRegistration: 配置 WebSocket 端点上的一个 STOMP.
4.17 WebMvcStompEndpointRegistry: 注册 WebSocket 端点上的 STOMP, 使用 HandlerMapping 映射端点.
4.18 WebMvcStompWebSocketEndpointRegistration: 配置 WebSocket/SockJS 端点上的 STOMP 的抽象基类.
4.19 WebSocketConfigurationSupport:WebSocket 请求处理的配置支持.
4.20 WebSocketConfigurer: 定义了回调方法, 通过 @EnableWebSocket 注解来配置 WebSocket 请求处理.
4.21 WebSocketHandlerRegistration: 提供了配置一个 WebSocket 处理器的方法.
4.22 WebSocketHandlerRegistry: 提供了配置 WebSocketHandler 请求映射的方法.
4.23 WebSocketMessageBrokerConfigurationSupport: 拓展自 AbstractMessageBrokerConfiguration, 增加了配置用于接收或者回应从 WebSocket 客户端来的 STOMP 消息.
4.24 WebSocketMessageBrokerConfigurer: 定义了使用来自 WebSocket 客户端的简单消息协议 (如 STOMP) 配置消息处理的方法.
4.25 WebSocketTransportRegistration: 配置从 WebSocket 客户端接收到的或发送过去的消息处理.
五, Web/socket/handler
5.1 AbstractWebSocketHandler: 带空方法的 WebSocketHandler 接口实现类的抽象基类.
5.2 BeanCreatingHandlerProvider: 通过 Spring BeanFactory 初始化一个目标处理器, 同样也提供一个等价的销毁函数. 主要在内部使用, 在每个连接生命周期中初始化和销毁处理器.
5.3 BinaryWebSocketHandler:WebSocketHandler 实现类的父类, 仅用于处理二进制消息.
5.4 TextWebSocketHandler:WebSocketHandler 实现类的父类, 仅用于处理文本消息.
5.5 ConcurrentWebSocketSessionDecorator: 封装一个 WebSocketSession, 以确保在一个时刻仅有一个线程可以发送消息.
5.6 ExceptionWebSocketHandlerDecorator: 一个异常处理 WebSocketHandlerDecorator. 捕捉所有从装饰处理器漏掉的 Trowable 实例, 使用 #SERVER_ERROR 关闭状态码关闭这个会话.
5.7 LoggingWebSocketHandlerDecorator: 继承自 WebSocketHandlerDecorator, 对 WebSocket 生命周期的事件增加了日志功能.
5.8 PerConnectionWebSocketHandler: 继承自 WebSocketHandler, 为每一个 WebSocket 连接初始化和销毁一个 WebSocketHandler 实例, 并将所有其他的方法委托给它.
5.9 SessionLimitExceededException: 当一个 WebSocket 会话超过了配置的限制会引发该异常, 比如事件, 缓冲区大小等等.
5.10 WebSocketHandlerDecorator: 封装另一个 WebSocketHandler 实例, 并代理它.
5.11 WebSocketHandlerDecoratorFactory: 对一个 WebSocketHandler 应用装饰器的工厂.
5.12 WebSocketSessionDecorator: 封装另一个 WebSocketSession 实例并代理它.
六, Web/socket/messaging
6.1 AbstractSubProtocolEvent: 从一个 WebSocket 客户端接收到一个消息并将其解析成更高级别的子协议 (如 STOMP) 的事件的抽象基类.
6.2 DefaultSimpUserRegistry:SimpUserRegistry 接口的默认实现类, 依赖于应用上下文事件来跟踪连接的用户及其订阅者.
6.3 SessionConnectedEvent: 一个连接事件, 表示服务器对客户单连接请求进行响应.
6.4 SessionConnectEvent: 当一个新的 WebSocket 客户端使用一个简单消息协议 (如 STOMP) 作为 WebSocket 子协议来发送一个连接请求时引发该事件.
6.5 SessionDisconnectEvent: 当 WebSocket 客户端使用一个简单消息协议 (如 STOMP) 作为 WebSocket 子协议的会话关闭时引发该事件.
6.6 SessionSubscribeEvent: 当一个新的 WebSocket 客户端使用一个简单消息协议 (如 STOMP) 来发送一个订阅请求时引发该事件.
6.7 SessionUnsubscribeEvent: 当一个新的 WebSocket 客户端使用一个简单消息协议 (如 STOMP) 发送一个请求去移除一个订阅时引发该事件.
6.8 StompSubProtocolErrorHandler: 使用 STOMP 的 SubProtocolErrorHandler.
6.9 StompSubProtocolHandler: 一个支持版本 1.0,1.1 和 1.2 的 STOMP 规范的 SubProtocolHandler.
6.10 SubProtocolErrorHandler: 处理发送到客户端的子协议错误.
6.11 SubProtocolHandler: 处理 WebSocket 消息, 作为更高级别协议的一部分, 被称作 WebSocket RFC 规范中的 "sub-protocol". 处理来自客户端的 WebSocketMessage 和发送到客户端的消息.
6.12 SubProtocolWebSocketHandler:WebSocketHandler 接口的实现类, 将收到的 WebSocket 消息委托给 SubProtocolHandler 和 MessageChannel.
6.13 WebSocketAnnotationMethodMessageHandler:SimpAnnotationMethodMessageHandler 子类, 提供了对带全局 @MessageExceptionHandler 方法的 ControllerAdvice 的支持.
6.14 WebSocketStompClient:WebSocket 客户端上的一个 STOMP, 使用 WebSocketClient 实现类包括 SockJSClient 进行连接.
七, Web/socket/server
7.1 HandshakeFailureException: 由于一个内部的, 无法恢复的原因导致握手处理无法完成抛出的异常. 这表示一个服务器错误(HTTP 状态码 500), 而不是握手协商时产生的失败.
7.2 HandshakeHandler: 处理一个 WebSocket 握手请求.
7.3 HandshakeInterceptor:WebSocket 握手请求的拦截器. 可以用来检查握手请求和响应, 也可以将参数传递给目标 WebSocketHandler.
7.4 RequestUpgradeStrategy: 一个服务器端特定的策略, 用于对一个 WebSocket 交互执行实际的 upgrade 操作.
Web/socket/server/jetty
7.5 JettyRequestUpgradeStrategy: 使用 Jetty 9.4 的 RequestUpgradeStrategy. 基于 Jetty 内部的 WebSocketHandler 类.
Web/socket/server/standard
7.6 AbstractStandardUpgradeStrategy: 基于标准的 WebSocket API 的 RequestUpgradeStrategy 接口实现类的抽象基类.
7.7 AbstractTyrusRequestUpgradeStrategy:RequestUpgradeStrategy 接口实现类的父类, 这些策略在基于 JSR-356 的服务器上实现, 其中包括 Tyrus 作为其 WebSocket 引擎.
适用于 Tyrus 1.11(WebLogic 12.2.1)和 Tyrus 1.12(GlassFish 4.1.1).
7.8 GlassFishRequestUpgradeStrategy: 一个用于 Oracle's GlassFish 4.1 和更高版本的 WebSocket RequestUpgradeStrategy.
GlassFish 是一款强健的商业兼容应用服务器, 达到产品级质量, 可免费用于开发, 部署和重新分发. 开发者可以免费获得源代码, 还可以对代码进行更改.
7.9 ServerEndpointExporter: 检测 ServerEndpointConfig 类型的 beans, 并使用标准的 Java WebSocket runtime 注册. 同时检测使用 ServerEndpoint 注解的 beans, 同样也对其进行注册.
7.10 ServerEndpointRegistration:ServerEndpointConfig 接口实现类, 在 Spring-based 应用中使用.
7.11 ServletServerContainerFactoryBean: 用于配置 ServerContainer 的 FactoryBean.
7.12 SpringConfigurator: 继承自 Configurator, 用于通过 Spring 初始化 ServerEndpoint 注解的类.
7.13 TomcatRequestUpgradeStrategy: 用于 Apache Tomcat 的 WebSocket RequestUpgradeStrategy. 兼容支持 JSR-356 的 Tomcat 的所有版本, 比如 Tomcat 7.0.47+ z 或者更高的版本.
JSR 356 (Java API for WebSocket) 指定 Java 开发人员在希望将 WebSocket 集成到应用程序 (同时在服务器端和 Java 客户端) 时可以使用的 API.WebSocket 协议的每一个声称符合 JSR 356 的实现都必须实现此 API.
7.14 UndertowRequestUpgradeStrategy: 用于 WildFly 和它的 Undertow Web 服务器的 WebSocket RequestUpgradeStrategy.
WildFly, 原名 JBoss AS(JBoss Application Server) 或者 JBoss, 是一套应用程序服务器, 属于开源的企业级 Java 中间件软件, 用于实现基于 SOA 架构 (面向服务的架构) 的 Web 应用和服务.
Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器.
7.15 WebLogicRequestUpgradeStrategy: 用于 Oracle 的 WebLogic 的 webSocket RequestUpgradeStrategy.
WebLogic 是 Oracle 公司出品的一个 application server, 确切的说是一个基于 Java EE 架构的中间件, WebLogic 是用于开发, 集成, 部署和管理大型分布式 Web 应用, 网络应用和数据库应用的 Java 应用服务器. 将 Java 的动态功能和 Java Enterprise 标准的安全性引入大型网络应用的开发, 集成, 部署和管理之中. Weblogic 就是和我们常用的 Tomcat 差不多的部署 Java Web 程序的服务器.
7.16 WebSphereRequestUpgradeStrategy:WebSphere, 支持在 WebSocket 握手时升级一个 HttpServletRequest.
WebSphere 是 IBM 的软件平台. 它包含了编写, 运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台, 跨产品解决方案所需要的整个中间件基础设施, 如服务器, 服务和工具. WebSphere 提供了可靠, 灵活和健壮的软件.
Web/socket/server/support
7.17 AbstractHandshakeHandler:HandshakeHandler 实现类的抽象基类, 独立于 Servlet API.
7.18 DefaultHandshakeHandler:HandshakeHandler 接口的默认实现类, 在父类 AbstractHandshakeHandler 基础上拓展了 Servlet-specific 初始化支持.
7.19 HandshakeInterceptorChain: 用于协助调用一列 handshake 拦截器.
7.20 HttpSessionHandshakeInterceptor: 拦截器, 用于将 HTTP 会话中的信息拷贝到 "handshake attributes" map 中.
7.21 OriginHandshakeInterceptor: 拦截器, 基于 "允许的 origins 值集合" 对请求 "Origin" 头的值进行检查.
7.22 WebSocketHandlerMapping: 继承自 SimpleUrlHandlerMapping, 同时实现了 SmartLifecycle, 传播 start 和 stop 调用到任意的处理器中. 这些处理器一般是 WebSocketHttpRequestHandler 或 SockJsHttpRequestHandler.
7.23 WebSocketHttpRequestHandler: 一个处理 WebSocket 握手请求的 HttpRequestHandler.
八, Web/socket/sockjs
SockJS 是一个浏览器上运行的 JavaScript 库, 如果浏览器不支持 WebSocket, 该库可以模拟对 WebSocket 的支持, 实现浏览器和 Web 服务器之间低延迟, 全双工, 跨域的通讯通道.
8.1 SockJsException: 处理 SockJS HTTP 请求引发的异常的父类.
8.2 SockJsMessageDeliveryException: 当通过 HTTP POST 方法成功接收和解析一个消息帧, 但是由于处理器失效或者连接关闭等原因, 该消息一个或多个帧不能被传递给 WebSocketHandler 时抛出该异常.
8.3 SockJsService: 处理来自 SockJS 客户端的 HTTP 请求消息的主入口. 在一个 Servlet 3 + 容器中, SockJsHttpRequestHandler 能够用来调用该服务.
8.4 SockJsTransportFailureException: 表示在 SockJS 实现中发生了一个严重的错误, 而不是在用户代码中(比如, 写入到响应时发送 I/O 错误). 当该异常引发时, SockJS 会话通常会关闭.
Web/socket/sockjs/client
8.5 AbstractClientSockJsSession:SockJS 客户端 WebSocketSession 实现类的父类. 提供了对到来的 SockJS 消息帧的处理, 委托 lifecyle 事件和消息给 WebSocketHandler 进行处理. 其子类要实现 send 和 disconnect.
8.6 XhrTransport: 一个 SockJS Transport, 使用 HTTP 请求来模拟一个 WebSocket 交互. connect 方法用来接收服务器来的消息, executeSendRequest()方法用来发送消息.
8.7 AbstractXhrTransport: 实现 XhrTransport 接口的抽象类.
8.8 TransportRequest: 该接口通过各种 get 方法来暴露信息, 主要被 Transport 和 session 实现, 关于连接到 SockJS 服务器端点的请求的相关信息.
8.9 DefaultTransportRequest:TransportRequest 接口的默认实现类.
8.10 InfoReceiver: 能够执行 SockJS "Info" 请求的组件, 需要在 SockJS 会话开始前执行, 以坚持服务器端点的能力, 比如这个端点是否允许使用 WebSocket.
8.11 JettyXhrTransport: 基于 Jetty 的 HttpClient 的 XHR transport.
xhr, 全称为 XMLHttpRequest, 用于与服务器交互数据, 是 Ajax 功能实现所依赖的对象, jQuery 中的 Ajax 就是对 xhr 的封装.
8.12 RestTemplateXhrTransport: 使用一个 RestTemplate 的 XhrTransport 实现类.
8.13 SockJsClient:WebSocketClient 的一个 SockJS 实现, 带了一个备用方案: 通过纯 HTTP 流和长轮询模拟一个 WebSocket 交互.
8.14 SockJsUrlInfo:SockJS 端点的基 URL 的容器, 附带获取相关 SockJS URLs 的方法: getInfoUrl()和 getTransportUrl(TransportType)
8.15 Transport: 一个客户端 SockJS transport 的实现.
8.16 UndertowXhrTransport: 基于 Undertow 的 UndertowClient 的 XHR transport.
Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器.
8.17 WebSocketClientSockJsSession: 继承自 AbstractClientSockJsSession, 封装和代理一个实际的 WebSocket 会话.
8.18 WebSocketTransport: 使用一个 WebSocketClient 的 SockJS Transport.
8.19 XhrClientSockJsSession: 继承自 AbstractClientSockJsSession, 使用 HTTP transports 模拟一个 WebSocket 会话.
Web/socket/sockjs/frame
8.20 AbstractSockJsMessageCodec:SockJS 消息编解码器的基类, 提供了 encode(String[])的实现.
8.21 DefaultSockJsFrameFormat:SockJsFrameFormat 接口的默认实现类, 依赖于 java.lang.String#format(String, Object...).
8.22 Jackson2SockJsMessageCodec: 一个 Jackson 2.6 + 编解码器, 用于对 SockJS 消息进行编码和解码.
8.23 SockJsFrame: 表示一个 SockJS 帧, 提供了创建 SockJS 帧的工厂方法.
8.24 SockJsFrameFormat: 将一个 transport-specific 格式应用到 SockJS 帧的内容中, 产生一个可以被写出的内容. 主要用在 HTTP 服务端 transports 推送数据.
8.25 SockJsFrameType: 枚举类, 枚举了 SockJS 帧的类型, 有 OPEN,HEARTBEAT,MESSAGE,CLOSE.
8.26 SockJsMessageCodec: 将一个消息编码到 SockJS 消息帧, 或从一个 SockJS 消息帧解码出消息, 本质上是一组 JSON 编码的消息. 例如: a["message1","message2"].
Web/socket/sockjs/support
8.27 AbstractSockJsService:SockJsService 实现类的抽象基类, 提供了 SockJS 路径解决方案, 处理静态 SockJS 请求(比如,"/info", "/iframe.html" 等等). 子类必须处理会话 URLs(比如, transport-specific 请求).
默认情况下, 只有同源的请求才允许. 使用 #setAllowedOrigins 方法指定一列允许的源.
8.28 SockJsHttpRequestHandler: 一个 HttpRequestHandler, 将一个 SockJsService 映射到在 Servlet 容器中的请求.
Web/socket/sockjs/transport
8.29 SockJsServiceConfig: 提供 transport 处理代码访问 SockJsServie 配置选项. 主要在内部使用.
8.30 SockJsSession:Spring 标准的 WebSocketSession 关于 SockJS 的拓展.
8.31 SockJsSessionFactory: 用于创建 SockJS 会话的工厂.
8.32 TransportHandler: 处理一个 SockJS 会话 URL, 比如 transport-specific 请求.
8.33 TransportHandlingSockJsService:SockJsService 的一个基本实现, 支持基于 SPI 的 transport 处理和会话管理.
8.34 TransportType: 枚举类, 枚举了 SockJS transport 类型. 有: websocket,xhr,xhr_send,xhr_streaming,eventsource,htmlfile.
Web/socket/sockjs/transport/handler
8.35 AbstractHttpReceivingTransportHandler:HTTP transport 处理器的基类, 通过 HTTP POST 方式接收消息.
8.36 AbstractHttpSendingTransportHandler:HTTP transport 处理器的基类, 推送消息到连接的客户端.
8.37 AbstractTransportHandler:TransportHandler 实现类的通用基类.
8.38 DefaultSockJsService:SockJsService 的默认实现, 带所有预先注册的默认 TransportHandler 实现类.
8.39 EventSourceTransportHandler: 一个 TransportHandler, 用于通过服务端发送事件来发送消息.
8.40 HtmlFileTransportHandler: 一个 HTTP TransportHandler, 使用知名的浏览器技术.
8.41 SockJsWebSocketHandler:WebSocketHandler 实现类, 增加了 SockJS 消息帧, 发送 SockJS 心跳消息, 委托生命周期事件和消息到一个目标 WebSocketHandler.
8.42 WebSocketTransportHandler: 基于 WebSocket 的 TransportHandler. 使用 SockJsWebSocketHandler 和 WebSocketServerSockJsSession 来增加 SockJS 处理.
8.43 XhrPollingTransportHandler: 基于 XHR 长轮询的 TransportHandler.
8.44 XhrReceivingTransportHandler: 一个 TransportHandler, 通过 HTTP 接收消息.
8.45 XhrStreamingTransportHandler: 一个 TransportHandler, 通过 HTTP 流请求来发送消息.
Web/socket/sockjs/transport/session
8.46 AbstractHttpSockJsSession: 用于 HTTP transport SockJS 会话的抽象基类.
8.47 AbstractSockJsSession:SockJsSession 接口实现类的抽象基类.
8.48 PollingSockJsSession: 用于轮询 HTTP transport 的 SockJS 会话.
8.49 StreamingSockJsSession: 用于流式 HTTP transport 的 SockJS 会话.
8.50 WebSocketServerSockJsSession: 用于 WebSocket transport 的 SockJS 会话.
参考:
[1] https://blog.csdn.net/fhadmin24/article/details/47055985
[2] https://www.cnblogs.com/xxkj/p/14273710.html
拓展阅读:
WebSocket 协议中文版
Spring 框架之 jdbc 源码完全解析
Spring 源码深度解析之数据库连接 JDBC
Spring 框架之 spring-webmvc 源码完全解析
Spring 源码深度解析之 Spring MVC
Spring 框架之 spring-Web Web 源码完全解析
Spring 框架之 spring-Web http 源码完全解析
Spring 框架之 jms 源码完全解析
Spring 框架之 AOP 源码完全解析
Spring 框架之 beans 源码完全解析
来源: http://www.bubuko.com/infodetail-3716594.html