Django длительный запрос на опрос по таймеру
- Django 3.2
- DRF
- run using ./mange runserver
- 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()
})
проблемы:
- 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
вопрос: Как ограничить количество получаемых запросов?
- 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)