Spring中配置WebSocket
Spring中配置WebSocket项目中需要在浏览器中实时查看 Docker 容器内框架的运行日志,在服务器上可以通过 docker 提供的 RESTful 接口, 获取 tail -f 的执行结果 InputStream 流. 而浏览器 HTTP 协议是一个请求 - 响应的协议, 要想获得数据, 就必须发起一次请求, 显然和 Java 的InputStream 的概念是
所以考虑使用 WebSocket 来实时获取日志流.
WebSocket简介
WebSocket为浏览器提供了一个真正的浏览器和服务器之间的全双工Channel. WebSocket使用HTTP的request protocol upgrade头部来进行请求建立, 服务端返回101表示协议切换成功, 底层的TCP Channel就会一直保持打开. 一旦通道建立, 浏览器端使用send()向服务器发送数据, 通过onmessage事件handler来接收服务器数据, 且每次发送数据时, 不需要再次传输HTTP Header, 大大减少了数据传输量, 适用于浏览器和服务器间进行高频率低延迟的数据交换. 同时实现了真正的服务器推送数据到浏览器.
浏览器端:
目前主流的浏览器都支持WebSocket.
浏览器 | 支持的版本 |
---|---|
Chrome | Supported in version 4+ |
Firefox | Supported in version 4+ |
Internet Explorer | Supported in version 10+ |
Opera | Supported in version 10+ |
Safari | Supported in version 5+ |
服务端:
JavaEE 7 JSR356提供了对WebSocket的支持, Tomcat从7.047版本开始提供了JSR356的支持, spring从4.0版本开始支持WebSocket.
Java 实现方法
在 Spring 端可以有以下几种方法使用 WebSocket
1. 使用 Java EE7 的方式
2. 使用 Spring 提供的接口
3. 使用 STOMP 协议以及 Spring 的 MVC
第三种方式见 Spring 的官方文档, 基于 webSocket, 使用 Simple Text Oriented Message Protocol(STOMP) 协议:Using WebSocket to build an interactive web application
STOM 协议工作在 Socket 之上, 类似于 HTTP 协议, 为面向于文本消息的中间件而设计, 是一种语言无关的协议, 符合该协议的 client 和 broker 之间都能通信, 无论是使用何种语言开发.
STOM 协议介绍
这里我将着重介绍使用 Spring 提供的接口开发的方式.
主要分为以下几个类, 第一个是 WebSocket 连接建立前的拦截类 HandshakeInterceptor, 类似于 Spring MVC 的 HandlerInteceptor, 第二个 WebSocket 的处理类, 负责对生命周期进行管理, 第三个是配置类, 将 websocket 请求与对应的 handler 类进行映射.
**1.HandshakeInterceptor
2.WebSocketHandler
3.WebSocketConfigurer**
依赖
Spring WebSocket 依赖于以下包, 版本为 4.0 版本及以上, Tomcat 7.047 以上版本, Java EE 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
HandshakeInterceptor
这个类类似于 Spring MVC 中用于拦截 HTTP 请求的 HandlerInteceptor. 它有两个方法,
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如果 beforeHandshake 返回 false, 那么该 WebSocket 请求被拒绝连接.
其中 request 可以转换成 ServletServerHttpRequest, 并获取其中包装的 HttpServletRequest, 以获得 http 请求中 parameter 等信息.
WebSocketHandler
作为 WebSocket 连接建立后的处理接口, 主要有以下方法.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
对于每个 WebSocket 连接, 传入的参数 session 都有一个唯一的 id, 通过 getId() 方法获取, 可用于标记这个 WebSocket 连接.
常用的类有 TextWebSocketHandler 和 BinaryWebSocketHandler. 这两个类继承自 AbstractWebSocketHandler, 其接收 message 时, 对 message 类型进行了判断, 并对不同类型的消息进行了分发. 使用时我们需要分别覆盖 handleTextMessage 方法或 handleBinaryMessage 方法.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
WebSocketConfigurer
上面我们定义了握手时需要的 HandlerShakeInteceptor 和对 WebSocket 进行业务处理的 WebSocketHandler, 我们还需要将访问连接与对应的 handler 以及拦截器关联起来.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
@Configuration 是 Spring 基于 Java 类的配置, 可以将 Spring 的 Bean 转换为 Spring 的配置.
其等效的 XML 配置如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
对于 java configuration 中的 setAllowedOrigins 和 xml 中的 allowed-origins, 解释一下, 这是用于设置跨域的, 简单的说就是一般浏览器对于 AJAX 和 WebSocket 是禁止跨域请求, 需要我们在服务器端进行设置, 允许其他域 (比如主机名不同或者端口不同) 上的网页与你的 WebSocket 发起连接. “*” 表示任何域上的网页请求都可以连接, 请设置为信任的域名.
客户端
1.Chrome 的 Dark WebSocket Terminal 应用
2.Java-WebSocket 包中的 client 类
3.JS
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
更多推荐
所有评论(0)