长轮询: 当服务器收到前端发来的请求后,服务器端不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,
如果一直没有数据,则到达一定的时间限制(服务器端设置)才返回,返回完之后,客户端再次建立连接,周而复始,基于事件的触发,一个事件接一个事件
长轮询处理流程:
1.访问接口地址的时候,后端为每个用户创建一个队列
2.前端发送内容,数据发送到后天,将数据存储到每个人的队列中
3.前端递归获取消息,去自己的队列中获取数据,然后在界面上显示
//前端
<script>
USER_UID = "{{ uid }}";
// 发送数据
function sendMessage() {
var text = $("#txt").val();
// 基于ajax将用户输入的文本信息发送到后台
$.ajax({
url: '/pool/send/msg/',
type: 'GET',
data: {
text: text
}
})
}
// 获取数据
function getMessage() {
$.ajax(
{
url: '/pool/get/msg',
type: 'GET',
dataType: 'JSON',
data: {
uid: USER_UID,
},
success: function (res) {
if (res.status) {
var tag = $("div");
tag.text(res.data)
$("#message").append(tag);
}
// 递归调用
getMessage();
}
}
)
}
$(function (){
getMessage();
})
</script>
# views
from django.shortcuts import render, HttpResponse
from django.http.response import JsonResponse
import queue
# Create your views here.
# 创建用户队列
USER_QUEUE = {}
def home(request):
# 获取当前访问用户uid
uid = request.GET.get('uid')
# 用户访问的时候,将当前用户存储到队列
USER_QUEUE[uid] = queue.Queue()
return render(request, 'home.html', {'uid': uid})
def send_msg(request):
# 获取用户发送到内容
text = request.GET.get('text')
for uid, q in USER_QUEUE.items()
q.put(text)
return HttpResponse('ok')
def get_msg(request):
# 当前用户uid
uid = request.GET.get('uid')
# 获取当前用户队列
q = USER_QUEUE[uid]
# 设置返回值
result = {'status': True, 'data': None}
try:
# 如果获取到数据,将数据传给 result['data'],队列超时时间为10s
data = q.get(timeout=10)
result['data'] = data
except queue.Empty as e:
# 如果10s没有新数据,将status设置为False返回
result['status'] = False
# 前端可以通过status 判断有没有新数据
return JsonResponse(result)
Q:服务端持有连接,服务器压力是不是很大?
A:如果基于IO多路复用 + 异步,可以解决这个问题