Django длительный запрос на опрос по таймеру

  1. Django 3.2
  2. DRF
  3. run using ./mange runserver
  4. when deploying planing to use 'nginx, uwsgi'

вот мой код бэкенда

class ChatHandler(APIView):
queryset = Chat.objects.all()
serialzier_class = MessageSerializer



def get_queryset(self):
    return self.queryset.filter(name=self.kwargs['room']).get()

def get(self, request, room):
    optionail_last_message_time  = request.data.get('at')
    new_messages = self.get_queryset().messages.filter(is_viewed=False)
    while not new_messages.exists():
        print(timezone.localtime().time(), 'no new messages')
        sleep(3)


    print(dir(self))
    print(dir(self.request))
    print('oh here it is')
    last_time = new_messages.last().created_at.timestamp()
    serializered_new_messages  = self.serialzier_class(instance=new_messages, many=True).data
    new_messages.update(is_viewed=True)

    return Response(
        {
            'messages': serializered_new_messages,
            'last_time': last_time,
            'initial': False
        }, status=200
    )

и вот код внешнего интерфейса

 function textRequest(last_time) {
    $.ajax({
        method:'GET',
        url:long_url,
        data: {'at': last_time},                
        timeout:2000,   
        success : (data, status, xqhr) => {
            console.log(last_time)
            let messages = data['messages']
            console.log(messages)
            if (messages) {
                for (let message of messages) {
                    console.log(message)
                    inject_message(message)
                }
            }

            setTimeout(()=>{
                textRequest(data['last_time'])
            }, 5000)    
        },
        error: (error, status_text, xqhr)=> {
            if ((error.readyState == 0) && (status_text =='timeout')) {
                console.log(status_text)
                textRequest()
                console.log('sent')
            }
        },
    })

}

window.addEventListener('load', ()=>{
    textRequest()
})

проблемы:

  1. when i make refresh to the page it sends a new request to the
    back-end, and will continue in its recreation sending the requests, and back-end server receives a hundreds of requests

вопрос: Как ограничить количество получаемых запросов?

  1. when the server finds the data, and processes it back to the front-end, the response doesn't arrive over there ' in front-end side' because the the request it is already died ' reached the timeout its limit'

Вопрос: Что я должен делать, чтобы избежать этого? вопрос: Есть ли способ узнать из бэкенда, достиг ли запрос своего таймаута?

request: не могли бы вы, пожалуйста, предоставить мне возможность реализовать длинный опрос в Django, я застрял в этой проблеме на несколько дней

спасибо заранее

Я смог заставить его работать с помощью следующего кода в бэкенде:

class ChatLongPolling(MainConfig):
serializer_class = MessageSerializer 

def get(self, request, name):
    messages = self.get_queryset().messages
    messages_filter = messages.filter(is_sent=False)
    while not messages_filter.exists():
        print('searching..')
        sleep(1)
        return JsonResponse({'empty':'empty'})
    else:    
        messages = self.serializer_class(instance=messages_filter, many=True).data
        messages_filter.update(is_sent=True)
        print(messages)
        return JsonResponse({'messages': messages})

а вот внешняя сторона

function make_json_request(url){
    let request = new XMLHttpRequest()
    request.open('get', url)
    request.responseType = 'json'
    request.addEventListener('load', function() {
        let response = request.response
        if (response['messages']){
            let messages = response['messages']
            console.log(messages)
            for (let message of messages) {
                append(message)
            }
        }
    });

    request.addEventListener('abort', function(){
        console.log('abort')
    });

    request.addEventListener('error', function(){
        console.log('error')
        setTimeout(()=>{make_json_request(url)}, 1000);
    });

    request.send()        
}

function get_all_messages(url){
    make_json_request(url)
}

function longpolling(url) {
    make_json_request(url)
    setTimeout(()=>{longpolling(url)}, 1000);
}

send_message()
get_all_messages(store_url)
longpolling(long_url)
Вернуться на верх