项目中需要在浏览器中实时查看 docker 容器内框架的运行日志, 在服务器上可以通过 docker 提供的 RESTful 接口, 获取 tail -f 的执行结果 InputStream 流. 而浏览器 HTTP 协议是一个请求 - 响应的协议, 要想获得数据, 就必须发起一次请求, 显然和 Java 的 InputStream 的概念是不能协作的, 服务器无法实时的将日志流推送到浏览器. 使用 AJAX 技术可以以一定的间隔时间异步方式发起请求. 在浏览器没有发起 AJAX 的时间间隙内, 服务器需要维持日志流的缓存, 如果有很多不同的页面查看日志, 那么就需要维持多个队列, 还有一个问题就是如果一个日志页面关闭了, 如何清除这个队列缓存?
所以考虑使用 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
<dependency>
<groupId>org.springframework</groupId>
<artifactId><