SpringMVC-04服务端推送技术

一、介绍

所有的服务器推送的方案都是基于:

当客户端像服务端发送请求,服务端会抓住这个请求不放,等有数据更新的时候才会返回给客户端,当客户端接收到消息的时候,再向服务端发送请求,周而复始。

这样做的好处是:减少了服务器请求的次数,减少了服务器的压力。

二、需求

分别使用SSE和基于Servlet3.0+异步方法,每5秒向浏览器推送随机消息。其中SSE需要新式浏览器的支持,Servlet3.0+是跨浏览器的。

三、实现

1.SSE
(1)Controller实现
package com.eleven.controller;

import java.util.Random;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // 该注解表示返回的是字符串,与页面直接渲染
public class SseController {

	@RequestMapping(value = "/push", produces = "text/event-stream") // 输出媒体的类型为event-stream,表示这是服务端SSE的支持,
	public @ResponseBody String push() {
		Random r = new Random(); // 创建一个随机数的对象
		try {
			Thread.sleep(5000); // 默认单位是millis,表示等待5秒钟
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "data:Testing 1,2,3" + r.nextInt() + "\n\n";
	}

}
(2)sse.jsp页面

在src/main/resources/views新建sse.jsp文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
	<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SSE Demo</title>
</head>
<body>
	<div id="msgFromPush">
		<script src="<c:url value="https://code.jquery.com/jquery-3.4.1.min.js"/>"></script>
		<script type="text/javascript">
			if (!!window.EventSource) { // EventSource对象只有新式浏览器才有,是SSE的客户端
				alert();
				var source = new EventSource('push');
				s = '';
				source.addEventListener('message', function(e) { // 添加SSE客户端监听,再此获得服务器推送的消息
					s += e.data + "<br/>";
					$("#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 {
				console.log("你的浏览器不支持SSE");
			}
		</script>
	</div>
</body>
</html>
(3)添加配置

在MyMvcConfig.java下面添加如下配置。

registry.addViewController("/sse").setViewName("sse");	// 添加转向sse.jsp页面的映射
(4)运行访问

访问:http://localhost:8080/springmvc/sse

在这里插入图片描述

2.基于Servlet3.0的异步支持方法
(1)开启异步方法支持

在WebInitializer.java里面加入,开启异步方法支持。

servlet.setAsyncSupported(true); // 开启异步方法支持
(2)Controller实现
package com.eleven.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import com.eleven.service.PushService;

@Controller	// 返回的是字符串,与html页面进行渲染
public class AsyncController {
	
	@Autowired
	private PushService pushService;	// 将PushService注入到AsyncController中,定时任务,定时更新DeferredResult
	
	@RequestMapping("/defer")
	@ResponseBody
	public DeferredResult<String> deferredCall(){	// 返回客户端DeferredResult
		return pushService.getAsyncUpdate();
	}

}

(3)Service定时任务
package com.eleven.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;	// 在PushService里面声明一个DeferredResult给控制器使用
	
	public DeferredResult<String> getAsyncUpdate() {
		deferredResult = new DeferredResult<String>();
		return deferredResult;
	}
	
	@Scheduled(fixedDelay = 5000)	// 定时更新DeferredResult
	public void refresh() {
		if(deferredResult != null) {
			deferredResult.setResult(new Long(System.currentTimeMillis()).toString());
		}
	}
	

}

(4)async.jsp页面

在src/main/resources/views下新建async.jsp页面。

因为此处的代码使用的是jQuery的Ajax请求,所以没有浏览器兼容性问题。

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
	<script type="text/javascript">
		deferred();	// 页面打开后就像后台发送请求

		function deferred() {
			$.get('defer', function(data) {
				console.log(data);	// 在控制台输出服务端推送的数据
				deferred();	// 一次请求完成后在继续像后台发送请求
			});
		}
	</script>
</body>
</html>
(5)添加配置

在MyMvcConfig.java加入注解,开始计划任务的支持.

并添加到Async.jsp页面的映射

@EnableScheduling // 开始计划任务的支持
registry.addViewController("/async").setViewName("async");	// 添加转向async.jsp页面的映射
(6)运行访问

输入地址:http://localhost:8080/springmvc02/async

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值