Spring框架之websocket源码完全解析
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
拓展阅读:
Spring框架之spring-web http源码完全解析