本节的服务端推送技术基于:当客户端向服务端发送请求,服务端会抓住这个请求不放,当有数据更新的时候才返回给客户端,当客户端接收到消息后,再向服务端发送请求,周而复始
1.演示控制器
package com.just.springmvc4.controller;
import java.util.Random;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 服务端推送
* 在消息体后面有两个换行符\n,代表当前消息体发送完毕,一个换行符标识当前消息并未结束,
* 浏览器需要等待后面数据的到来后再触发事件;
*/
@RestController
public class SSEController {
@RequestMapping(value ="/push",produces = "text/event-stream;charset=UTF-8")
public String sse(){
Random r=new Random();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "data:当前增加的收入:"+r.nextInt(1000)+"元"+"\n\n";
}
}
注意推送的数据格式后面要有\n\n,输出的媒体类型为:text/event-stream,这是服务器端SSE的支持
2.演示页面
新建sse.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SSE服务端推送测试</title>
<style>
h1{
color:red;
}
</style>
</head>
<body>
<div id="msgFromPush"></div>
<script src="../assets/js/jquery-3.3.1.min.js" type="text/javascript"></script>
<script>
/**
* HTML5规范中提供了服务端事件EventSource,浏览器在实现了该规范的前提下创建一个EventSource连接后,
* 便可收到服务端的发送的消息,这些消息需要遵循一定的格式,
* 对于前端开发人员而言,只需在浏览器中侦听对应的事件皆可。
* 浏览器端,需要创建一个EventSource对象,并且传入一个服务端的接口URI作为参数。
*/
if(!!window.EventSource){
var source=new EventSource("push");
s='';
source.addEventListener('message',function (e) {
s+="<h1>"+e.data+"</h1>";
$("#msgFromPush").html(s);
});
source.addEventListener('open',function (e) {
console.log("连接打开");
},false);
source.addEventListener('error',function (e) {
if(e.readyState==EventSource.CLOSED){
console.log("连接关闭");
}else{
console.log(e.readyState);
}
},false);
}else{
alert("当前这个渣渣浏览器不支持SSE");
}
</script>
</body>
</html>
EventSource只有新式的浏览器才有,所以这种推送技术有局限性,且不支持跨域
至于jsp页面的ViewController配置这里就不多讲了。
3.演示效果
如下图所示:
1.servlet配置文件开启异步方法支持
//注册DispatcherServlet
ServletRegistration.Dynamic servlet=servletContext.addServlet("dispatcher",new DispatcherServlet(context));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
servlet.setAsyncSupported(true); //开启异步方法的支持
2.异步任务控制器
package com.just.springmvc4.controller;
import com.just.springmvc4.service.PushService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
@RestController
public class AsyncController {
@Autowired
private PushService pushService;
@RequestMapping(value = "/defer",produces = "text/html;charset=UTF-8")
public DeferredResult<String> deferredCall(){
return pushService.getAsyncUpdate();
}
}
3.定时任务
定时更新DeferredResult
package com.just.springmvc4.service;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
@Service
public class PushService {
private DeferredResult<String> deferredResult;
public DeferredResult<String> getAsyncUpdate(){
deferredResult=new DeferredResult<String>();
return deferredResult;
}
@Scheduled(fixedDelay = 3000)
public void refresh(){
if(deferredResult!=null){
deferredResult.setResult("当前时间戳:"+System.currentTimeMillis());
}
}
}
4.演示页面
新建async.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>servlet async support</title>
</head>
<body>
<div id="content">
</div>
<h1 id="text"></h1>
<script src="../assets/js/jquery-3.3.1.min.js" type="text/javascript"></script>
<script>
deferred();
function deferred() {
$.get('defer',function (data) {
$("#content").append("<h1>"+data+"</h1>");
deferred();
})
}
</script>
</body>
</html>
5.MVC开启计划任务的支持
在MyMvcConfig类上加上注解
@EnableScheduling
6.演示效果
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/100310.html原文链接: