在 threading.Thead 中使用 Django 频道

Using django channels with threading.Thead

我正在使用 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

我使用线程能够在数据发送到客户端时监听 pause 和其他事件。 问题是线程在 websocket 断开连接后保持 运行。

有没有办法在 disconnect 函数中终止 python 线程?或者也许是更好的实现方式?

可能有很多方法可以解决您的问题。我建议您使用 asgiref.sync 中的函数 sync_to_async()。它创建一个新线程和 "awaits",直到完成。 "awaits" 意味着,在异步上下文中,其他代码可以同时 运行。

要调用 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