【webSocket】长轮询

API.PY

import queue
from django.contrib.auth.hashers import check_password
from rest_framework.views import APIView
from Databases import models
from django.http import JsonResponse
import traceback
from utils import common_md5
from django.contrib.auth.hashers import make_password

from utils.computer_time import now

QUEUE_DICT={}

class Login(APIView):
    permission_classes = []
    authentication_classes = []

    def post(self, request):

        username = str(request.data.get("username"))
        password = str(request.data.get("password"))

        message = {}
        try:
            # auth password
            md5_password = models.UserInfo.objects.filter(username=username).values('password')[0]['password']
            res = check_password(password, md5_password)

            if not res:
                message['code'] = 444
                message['message'] = "账号或者密码错误"
                return JsonResponse(message)

            # made token
            t = common_md5.md5(username)
            # get user_id object
            user_obj = models.UserInfo.objects.filter(username=username).first()
            # if  exist update || if not add data
            models.Token.objects.update_or_create(user=user_obj, defaults={'token': t})
            # madke token "31e02e07d0b010769d847e40e1a1bb19:123:7:True"
            token = t + ":" + username + ":" + str(user_obj.pk) + ":" + str(user_obj.is_staff)

            # 将登录的用户设置一个消息队列
            QUEUE_DICT[username] = queue.Queue()

            message['code'] = 200
            message['token'] = token
            return JsonResponse(message)
        except:
            print(traceback.print_exc())
            message['code'] = 444
            message['message'] = "登录失败"
            return JsonResponse(message)




class Register(APIView):
    permission_classes = []
    authentication_classes = []

    def post(self,request):

        username = str(request.data.get("register_username"))
        password = str(request.data.get("register_password"))

        message = {}
        # create user
        try:
            # made user md5 password
            models.UserInfo.objects.create(username=username, password=make_password(password))
            message['code'] = 200
            message['message'] = "注册成功"
            return JsonResponse(message)
        except Exception as e:

            message['code'] = 444
            message['message'] = "注册失败"
            return JsonResponse(message)



class MeesageSend(APIView):
    """
        每次发送都给每个人的队列放一个消息
    """
    def post(self,request):

        msg = request.data.get('msg')
        message = {}
        try:
            # 给每个用户队列添加消息
            for i in QUEUE_DICT.values():
                i.put(now() + "---" + request.user + "---" + msg)

            message['code'] = 200
            return JsonResponse(message)
        except Exception as e:
            message['code'] = 444
            return JsonResponse(message)



class MeesageGet(APIView):

    def get(self,request):
        message = {}
        try:
            # 每个用户获取自己的队列消息
            q = QUEUE_DICT[request.user]
            data = q.get(timeout=600)
            message['code'] = 200
            message['data'] = data
        except queue.Empty as e:
            message['code'] = 444
        return JsonResponse(message)

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Talking</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
    <style>
        #taking {
            width: 100%;
            height: 700px;
            background: #42fbff;
        }
    </style>
</head>
<body>
<div id="app" class="container">
    <div class="card-header">在线聊天室</div>
    <div id="taking">
        <ul v-for="item in talking">
            <li>{%verbatim %} {{ item }}{% endverbatim %}</li>
        </ul>
    </div>
    <div style=" 100%;height: 80px">
        <textarea type="text" v-model="msg" placeholder="请输入内容" style=" 100%;height: 100%"></textarea>
    </div>
    <button class="btn btn-primary" style=" 100px" @click="send">发送</button>
</div>
</body>
</html>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            username: "",
            msg: "",
            talking:[]
        },
        created() {
            axios.defaults.headers.common['authenticate'] = sessionStorage.getItem('token')
            // 判断是否已经登录
            this.username = sessionStorage.getItem("username");
            if (this.username == null) {
                window.location.href = "/login"
            }

            this.fun()

        },


        methods: {
            send() {
                axios.defaults.headers.common['authenticate'] = sessionStorage.getItem('token')
                axios.post('/send/message/', {
                    msg: this.msg,
                })
                    .then(response => {
                        if (response.data['code'] == 200) {
                            alert("发送成功")
                        } else if (response.data['code'] == 444) {
                            alert("发送失败")
                        }
                    }).catch(error => {
                    console.log(error)
                    alert("请求异常")
                })
            },

            fun() {
                console.log("111111")
                axios.get('/get/message/', {})
                    .then(response => {
                        if (response.data['code'] == 200) {
                            this.talking.push(response.data.data)
                        } else if (response.data['code'] == 444) {

                        }
                        this.fun()
                    }).catch(error => {
                    console.log(error)
                    alert("断开连接")
                })
            }


        },
    })
</script>

原文地址:https://www.cnblogs.com/wanghong1994/p/13991991.html