Как проверить не отключился ли клиент от Django websocket?
Стоит задача:
Клиент устанавливает Websocket с Django. Использую django 2.0 и channels 2.1.1 . В channels запускается задача, которая может занять очень длительное время - отправляются запросы на разные серверы и при получении ответов происходит отсылка обработанной информации в сокет клиенту. Если клиент закрыл страницу или отвалился интернет, сервер этого никак не определяет, а продолжает выполнение, как будто сокет живой. Каким образом организовать опрос клиента (отсылка heartbeat), живой он или отвалился, и в случае, если отвалился, закрывать сокет и прекращать выполнение скрипта?
Оказалось, что вебсокет закрывается, а вот выполнение цикла внутри нет. Каким образом можно остановить выполнение цикла внутри Consumer при disconnect?
Код выглядит так:
class MyConsumer(WebsocketConsumer):
def connect(self):
start = datetime.datetime.now()
self.accept()
print('socket opened')
urls = [.... list with urls ....]
for counter, url in enumerate(urls, 1): # Цикл, который нужно оборвать при отключении сокета
response = requests.get(url).json()
print(counter, response)
self.send(json.dumps({'progress': '{:.0f}%'.format(counter * 100 / len(urls)),
'data': response}))
print('Process time is: ', (datetime.datetime.now() - start).seconds)
self.close()
def disconnect(self, code):
print('socket closed')
# Тут нужно как-то отловить выполнение цикла и оборвать его выполнение
Сергей Горностаев, пробовал таким образом делать. Однако, находясь в цикле, значение переменной не меняется. Удалось решить проблему засунув цикл в отдельный тред.
class ScanFriendsConsumer(WebsocketConsumer):
def connect(self):
self.accept()
def task():
t = threading.current_thread()
urls = [.... list with urls ....]
for counter, url in enumerate(urls, 1):
if getattr(t, "do_run", True):
response = requests.get(url).json()
self.thread = threading.Thread(target=task)
self.thread.start()
def disconnect(self, code):
print('socket disconnected')
self.thread.do_run = False
self.thread.join()
Сергей Горностаев, пробовал использовать AsyncWebsocketConsumer, однако не понял как решить проблему того, что сообщения в сокет он отсылает только по завершении работы всего цикла. Может неправильно использовал