django 频道 channels.exceptions.Channels Full

Posted

技术标签:

【中文标题】django 频道 channels.exceptions.Channels Full【英文标题】:django channles channels.exceptions.Channels Full 【发布时间】:2018-10-27 06:28:23 【问题描述】:

我是 django-channels 和 python 的新手,我使用 django-channels 和 django 制作了一个演示,以主动将数据从后端发送到前端。 consumer.py 中的代码如下:

websocket_clients = []

class WebsocketConsumer(AsyncWebsocketConsumer):       
    def __init__(self, *args, **kwargs):
    """
    initial a new thread when new websocket instance initialed.
    """
    super(WebsocketConsumer, self).__init__(self)
    self.index_websocket = GendataThread()


    async def connect(self):
        self.index_websocket.channels_name = self.channel_name
        print('channel_name', self.channel_name)
        self.index_websocket.start()
        websocket_clients.append(self.channel_name)
        await self.accept()


    async def disconnect(self, close_code):
        """disconnected a websocket instance, and stop the thread."""

        self.index_websocket.stop()
        time.sleep(2)
        index = websocket_clients.index(self.channel_name)
        websocket_clients.pop(index)


    async def receive(self, text_data):
        """receive message from connected client, wouldn't work in this project."""
        text_data = '"message": "%s"' % (text_data)
        text_data_json = json.loads(text_data)


    async def chat_message(self, event):
    """send message to websocket."""
        print('event', event)
        await self.send(text_data=json.dumps(
        'message': event['message']))


def websocket_send_data(data, channel_name):
    """
    send data to front in websocket protocol,
    :param data: data which will be sent,
    :param channel_name: a symbol to mark connected client.
    :return:
    """
    channel_layer = get_channel_layer()
    event = 
        "type": "chat.message",
        "message": data
    
    async_to_sync(channel_layer.send)(channel_name, event)

如你所见,我创建了一个函数名:websocket_send_data(data, channel_name),我可以在 GendataThread() 中调用如下:

class GendataThread(threading.Thread):
    """new thread
    thread for getting data from cluster, and send to front with websocket protocol.
    """
    def __init__(self, *args, **kwargs):
        super(GendataThread, self).__init__(*args, **kwargs)
        self.channels_name = None

    def run(self):
        while true:
          websocker_send_data('1', self.channels_name)

在这种情况下,我可以在 django 项目运行时将数据从后端发送到前端,我连接到 url

ws://127.0.0.1:8000/ws/intime_data

在routing.py中设置如下:

websocket_urlpatterns = [
    url(r'^ws/intime_data$', consumers.WebsocketConsumer),
] 

我可以在前面接收数据,但是运行了几分钟,事情就出错了:

aioredis.errors.ReplyError: OOM command not allowed when used memory > 'maxmemory'.

我认为是因为redis通过保存数据已满,但我不想要这些数据,我尝试通过以下方式配置redis.conf:

maxmemory-policy allkeys-lru 

但在使用 maxmemory 时仍然会出现错误。有时会出现这样的错误:

channels.exceptions.Channels Full

我认为频道正在使用 redis 作为缓存,但我不知道为什么会出现错误,有人可以帮助我吗?提前致谢。

【问题讨论】:

你用的是什么层?例如,InMemoryChannelLayer 用户使用 python Queue 对象,因此它会很快填满。 嘿,我正在使用 redis_layer,因为 InMemoryChannelLayer 不再可用,因为通道版本高达 2.0。 【参考方案1】:

您将此代码添加到您的settings.py

CHANNEL_LAYERS = 
    "default": 
        "BACKEND": "asgi_redis.RedisChannelLayer",
        "CONFIG": 
            "hosts": [(XXX, XXX)],
        ,
        "ROUTING": "XXXXXchannel_routing"
    ,
 

【讨论】:

以上是关于django 频道 channels.exceptions.Channels Full的主要内容,如果未能解决你的问题,请参考以下文章

使用 django 频道时如何使用频道而不是组?

Django 频道“组订阅中 N 个频道中的 ERROR Y 超出容量”

使用 django 频道的 heroku 的正确 procfile / 要求是啥?

django 频道集成问题,websocket.receive 不听

未处理 Django 频道 websocket.receive

在 nginx 上部署 django 频道