最近遇到一个需求:需要开发一个页面,能够像jenkins那样,执行服务器上的shell脚本,并且将脚本信息实时显示到页面上。由于脚本功能很复杂,执行的时间很长,而且执行过程中的信息需要实时显示出来。所以使用传统http的请求-响应方式无法实现,于是开始调研这一需求如何实现,以下是调研过程。
这种需求是典型的“服务器推送技术”(ServerPushing),它是继“Ajax”之后又一个倍受追捧的Web技术。类似的需求有:聊天室、实时监控(服务端将监控数据推到图表中)...在早期要实现这种功能通常使用:
- 轮询:即每隔一段时间发送一个ajax请求,返回数据;
- 长连接:由Browser端主动发起请求,但是Server端以一种似乎非常慢的响应方式给出回答。这样在这个期间内,服务器端可以使用同一个connection把要更新的数据主动发送给Browser。因此请求可能等待较长的时间,期间没有任何数据返回,但是一旦有了新的数据,它将立即被发送到客户机。
- flash:略
- java applet:略
上面这几种方式比较旧,后两种几乎退出了历史舞台。接下来我们看一下最新的技术进展。
1、DWR:
dwr是随着ajax技术流行起来的,被称为“反向ajax”。dwr优势:可以实现js中直接调用后端java方法;java中的方法也可以调用js前端定义的方法;以及反向ajax的服务器推技术。
1)dwr原理是:客户端的engine.js作为客户端的引擎,服务端的dwr.jar作为服务端的引擎,二者以“RPC”的方式来获取数据。
- dwr.xml中定义的java类会被转换成对应的javascript对象(用到了反射技术);
- 当前端调用java方法时,DWR会封装一个ajax请求到后端的dwr servlet(实际上DWR还是用的ajax,只不过是封装了一层)
- 在engine.js和dwr.jar的帮助下,实现java和javascript之间可以相互调用;
https://blog.csdn.net/zy_281870667/article/details/53080750
2)dwr反向Ajax主要两种模式:主动、被动模式,其中主动模式包括polling和comet两种,被动模式只有piggyback这一种。
- piggyback:这是默认的方式。如果后台有什么内容需要推送到前台,是要等到那个页面进行下一次ajax请求的时候,将需要推送的内容附加在该次请求之后,传回到页面。只有等到下次请求页面主动发起了,中间的变化内容才传递回页面。
- comet方式:当服务端建立和浏览器的连接,将页面内容发送到浏览器之后,对应的连接并不关闭,只是暂时挂起。如果后面有什么新的内容需要推送到客户端的时候直接通过前面挂起的连接再次传送数据。服务器所能提供的连接数目是一定的,在大量的挂起的连接没有关闭的情况下,可能造成新的连接请求不能接入,从而影响到服务质量。
- polling方式:由浏览器定时向服务端发送ajax请求,询问后台是否有什么内容需要推送,有的话就会由服务端返回推送内容。这种方式和我们直接在页面通过定时器发送ajax请求,然后查询后台是否有变化内容的实现是类似的。只不过用了dwr之后这部分工作由框架帮我们完成了。
https://www.iteye.com/blog/xinklabi-1905195
2、SSE:
SSE是HTML5新增的功能,全称为Server-Sent Events,它可以允许服务推送数据到客户端。严格地说,HTTP 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息(streaming),即:发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 HTTP 协议,目前除了 IE/Edge,其他浏览器都支持。
SSE 是单向通道,只能服务器向浏览器发送,因为流信息本质上就是下载。如果浏览器向服务器发送信息,就变成了另一次 HTTP 请求。
这里就不详细介绍,详情见:https://blog.csdn.net/liuxiao723846/article/details/103881383
3、webSocket:
WebSocket是Html5定义的一个新协议,与传统的http协议不同,该协议可以实现服务器与客户端之间全双工通信。简单来说,首先需要在客户端和服务器端建立起一个连接,这部分需要http。连接一旦建立,客户端和服务器端就处于平等的地位,可以相互发送数据,不存在请求和响应的区别。
1)自己搭建websocket服务器,即springboog+websocket+js,后端部署到tomcat中,前端使用js的websocket框架。
详情见:https://blog.csdn.net/liuxiao723846/article/details/103888438
2)websocketd+js:
WebSocketd是WebSocket的守护进程,负责处理WebSocket连接,并启动服务器应用程序来处理WebSockets,在应用程序和Web浏览器之间传递消息。WebSocketd是一款非常特别的WebSocket服务器,它的最大特点是后台脚本不限语言,其标准输入stdin就是WebSocket的输入,标准输出stdout就是WebSocket的输出。
WebSocketd本质上是命令行的WebSocket代理,只要在命令行可以执行的程序,都可以通过它与浏览器进行WebSocket通信,WebSocketd可作为后台服务运行,帮助处理WebSocket连接,加载应用程序处理WebSocket,在程序和浏览器之间传递消息,无需任意依赖包且进程独立。
websocketd下载地址:https://github.com/joewalnes/websocketd/releases
详细使用见:https://blog.csdn.net/liuxiao723846/article/details/103887306