服务端向客户端推送消息
- 轮询
- 长轮询
- websocket
轮询(效率极低,基本不用)
"""
让浏览器定时(例如每隔5秒发一次)通过ajax朝服务端发送请求获取数据
缺点:
消息延迟严重
请求次数多 消耗资源过大
"""
长轮询(兼容性好)
"""
服务端给每个浏览器创建一个队列,让浏览器通过ajax向后端偷偷的发送请求,去各自对应的队列中获取数据,如果没有数据则会有阻塞,但是不会一直阻塞,比如最多阻塞30秒(pending)后给一个响应,无论响应是否是真正的数据,都会再次通过回调函数调用请求数据的代码
有点:
消息基本没有延迟
请求次数降低 消耗资源减少
"""
# 大公司需要考虑兼容性问题 追求兼容 目前网页版本的微信和qq用的就是长轮询
# ps:给标签绑定事件的方式大致有两种
# 1标签查找绑定
$('p').click()
# 2直接写函数 注意括号不能少
<p onclick="sendMsg()"></p>
基于ajax,队列以及异常处理实现简易版本的群聊功能(长轮询)
后端
import queue
q_dict = {} # {唯一标示:对应的队列,唯一标示:对应的队列}
def home(request):
# 获取客户端浏览器的唯一标识
name = request.GET.get('name')
# 生成一一对应关系
q_dict[name] = queue.Queue()
return render(request,'home.html',locals())
def send_msg(request):
if request.method == 'POST':
# 获取用户发送的消息
message = request.POST.get('content')
print(message)
# 将消息给所有的队列发送一份
for q in q_dict.values():
q.put(message)
return HttpResponse('OK')
def get_msg(request):
# 获取用户唯一标示
name = request.GET.get('name')
# 获取对应的队列
q = q_dict.get(name)
back_dic = {'status':True,'msg':''}
try:
data = q.get(timeout=10)
back_dic['msg'] = data
except queue.Empty as e:
back_dic['status'] = False
return JsonResponse(back_dic)
前端
<h1>聊天室:{{ name }}</h1>
<input type="text" id="txt">
<button onclick="sendMsg()">提交</button>
<h1>聊天记录</h1>
<div class="record">
</div>
<script>
function sendMsg() {
// 朝后端发送消息
$.ajax({
url:'/send_msg/',
type:'post',
dataType:'JSON',
data:{'content':$('#txt').val()},
success:function (args) {
}
})
}
function getMsg() {
// 偷偷的朝服务端要数据
$.ajax({
url:'/get_msg/',
type:'get',
data:{'name':'{{ name }}'},
success:function (args) {
if (args.status){
// 获取消息 动态渲染到页面上
// 1 创建一个p标签
var pEle = $('<p>');
// 2 给p标签设置文本内容
pEle.text(args.msg);
// 3 将p标签添加到div内部
$('.record').append(pEle)
}
getMsg()
}
})
}
// 页面加载完毕立刻执行
$(function () {
getMsg()
})
</script>