在Web应用开发中,我们会经常需要实时响应数据,例如:网页聊天室、实时更新网页在线人数等很多的应用场景。我们前后端数据的交互,通常使用ajax进行交互,所以下面的两种方法都是基于ajax交互技术。
下面我先给大家一个应用场景:网页聊天室,对方发信息过来,我们的前端界面必须马上响应出来,我们发信息过去,对方也要马上响应到前端界面。
解决问题的思路:
1.前端要不停地向后端发送请求(ajax请求)
2.两个人的聊天记录可以放置于缓存中(redis)
3.每次ajax访问请求,把缓存中的聊天数据重新响应到前端
短轮询,不停的询问请求,而且每次请求时间特别短,这就意味着前端要每隔很短的时间就发送一次ajax请求,不停的响应缓存中的数据到前端界面。这势必会增加服务器的压力,但是我还是将这样一种思想用代码展示下。
//刷新聊天
function flush() {
$.ajax({
url: "text",
type: "POST",
data: {name:name},
async: false,
success: function (data) {
$(data).each(function () {
//成功回调函数,遍历data数据,进行前端渲染,这里自由发挥
})
},
error: function (XMLHttpRequest) {
alert(XMLHttpRequest.status);
}
});
setTimeout("flush()",1000); //一秒中后再次调用flush()方法 ,就这样不停的短轮询
}
后端的请求大家就自由发挥了,你想要返回什么数据就返回什么数据,前端想怎么渲染就怎么渲染。
大家可以看到,短轮询以如此速度发送请求将给服务器造成巨大的压力,所以我推荐大家使用长轮询,下面就给大家介绍。
长轮询概念:前端向服务器发送请求,一直保持着请求,直到服务器响应才结束这次请求,相比于短轮询的发送请求次数,可以说长轮询是巨大的优化。
类似于:好友发送消息给我,才局部响应到我的聊天界面,不用一直去请求刷新。
//这是前端的ajax请求
function longConnection() {
$.ajax({
url : "long",
type : "POST",
success : function(data) {
if(data=="flush"){
alert("刷新");//后端请求判断返回字符串
}
longConnection(); //结束这次请求后,再次调用本身方法
},
error : function(XMLHttpRequest) {
alert(XMLHttpRequest.status);
longConnection();//发生异常错误后再次发起请求
}
});
}
//光看前端的ajax请求看不出什么,看看后面的后端请求
@Controller
public class LongConnectionController {
@Autowired
private RedisTemplate redisTemplate;
private static final long TIMEOUT = 20000;// 超时时间设置为20秒,这个时间随便你设置
//我设置20s,代表我这次请求最多维持20s
@RequestMapping("/long")
@ResponseBody
public String longConnection(HttpSession session)throws Exception{
String msg="";
long requestTime = System.currentTimeMillis(); //获取进入请求时间
while(System.currentTimeMillis()-requestTime
我解释下上面的代码:
前端发送ajax请求过来,后端并不会马上响应,自然维持了这次请求的时间。后端请求设置了20s的超时时间,用一个while循环加时间戳循环20s,当判断有新消息时,马上break出while循环,返回数据给前端。
所以只要判断没有新消息,while循环就会维持20s,即这个请求会维持20s,当然我们可以设置更长的时间,这都不影响。