websocket Django引导消费者如何在服务器端断开连接

sg2wtvxw  于 2023-06-06  发布在  Go
关注(0)|答案(1)|浏览(204)

我尝试用django,channels写一个日志文件查看器,但只有第一个连接工作正常,当我刷新前端时,WebSocket会连接失败。经过一些搜索,我发现循环仍然在我的代码中运行(第一个WebSocket连接没有正确清理)。我想当我关闭WebSocket客户端时会调用disconnect,但事实并非如此。
我的消费者代码:

import time
from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumer
class LogConsumer(WebsocketConsumer):
    end = False
    def connect(self):
        self.accept()
        filename = self.scope['url_route']['kwargs']['filepath']
        file_fullname = "/tmp/" + filename
        print('file name: %s' % file_fullname)
        with open(file_fullname, 'r') as f:
           while True:
               time.sleep(1)
               if self.end:
                   break
               new_line = f.readline()
               print('Loop is still running ....')
               if new_line:
                   print('sending data: %s' % new_line)
                   self.send(text_data=new_line)

    def disconnect(self, event):
        print('websocket disconnected...', event)
        self.end = True
        raise StopConsumer()

daphne输出:

192.168.1.2:63267 - - [03/Jun/2023:16:25:09] "WSCONNECTING /ws/message/" - -
192.168.1.2:63267 - - [03/Jun/2023:16:25:09] "WSCONNECT /ws/message/" - -
file name: /tmp/message
Loop is still running ....
sending data:

Loop is still running ....
sending data: 1

Loop is still running ....
sending data: 2

Loop is still running ....
sending data: 3

192.168.1.2:63267 - - [03/Jun/2023:16:25:14] "WSDISCONNECT /ws/message/" - -
192.168.1.2:63273 - - [03/Jun/2023:16:25:14] "WSCONNECTING /ws/message/" - -
Loop is still running ....
sending data: 4

Loop is still running ....
sending data: 5
zf9nrax1

zf9nrax11#

消费者被send()中的循环阻塞。所以我在线程中重写循环。解决了
固定代码如下:

class LogConsumer(WebsocketConsumer):
    end = False
    def connect(self):
        self.accept()
        self.thread = threading.Thread(target=self.action)
        self.thread.start()

    def action(self):
        filename = self.scope['url_route']['kwargs']['filepath']
        file_fullname = "/tmp/" + filename
        print('file name: %s' % file_fullname)
        with open(file_fullname, 'r') as f:
           while not self.end:
               if self.end:
                   break
               new_line = f.readline()
               # print('Loop is still running ....')
               if new_line:
                   print('sending data: %s' % new_line)
                   self.send(text_data=new_line)

    def disconnect(self, event):
        print('websocket disconnected...', event)
        self.end = True
        raise StopConsumer()

相关问题