服务端向客户端推送消息的几种方式,基于ajax,队列以及异常处理实现简易版本的群聊功能(长轮询)

服务端向客户端推送消息

  • 轮询
  • 长轮询
  • 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>
原文地址:https://www.cnblogs.com/yafeng666/p/12691910.html