Использование каналов Django с потоками. - PullRequest
0 голосов
/ 01 ноября 2018

Я использую каналы django для отправки нескольких ответов на один запрос. Код выглядит примерно так:

class terminal(WebsocketConsumer):
   def connect(self):
       self.accept()

   def disconnect(self, close_code):
       self.close()

   def receive(self, text_data):
       data_json = json.loads(text_data)
       if data_json['event'] == 'initial':
          self.t = threading.Thread(target=self.send_data)
          self.t.daemon = True
          self.t.start()
       elif data_json['event'] == 'pause':
          pass
       print("done")

   def send_data(self):
       n = 100
       end = 1000000
       while (n + 1 < end)
          # some code
          self.send(json.dumps({'data':data})
          n += 1

Я использовал поток, чтобы иметь возможность прослушивать пауза и другие события во время отправки данных клиенту. Проблема заключается в том, что поток продолжает работать после отключения websocket.

Есть ли способ убить поток Python в функции отключить ? Или, может быть, лучший способ реализовать это?

1 Ответ

0 голосов
/ 11 ноября 2018

Вероятно, есть много способов решить вашу проблему. Я бы посоветовал вам использовать функцию sync_to_async() из asgiref.sync. Он создает новый поток и «ждет», пока не закончится. «ожидает» означает, что в асинхронном контексте другой код может выполняться в это время.

Для вызова sync_to_async() необходимо использовать AsyncWebsocketConsumer

class terminal(AsyncWebsocketConsumer):
   async def connect(self):
       awaitself.accept()

   async def disconnect(self, close_code):
       await self.close()

   async def receive(self, text_data):
       data_json = json.loads(text_data)
       if data_json['event'] == 'initial':
          await sync_to_async(self.send_data)()
       elif data_json['event'] == 'pause':
          pass
       print("done")

   def send_data(self):
       n = 100
       end = 1000000
       while (n + 1 < end)
          # some code
          sync_to_async(self.send)(json.dumps({'data':data})
          n += 1
...