首页 > 解决方案 > Django 频道“名称解析暂时失败”,我不知道该怎么办

问题描述

我正在松散地遵循 YouTube 上的教程,试图对实现频道有一个基本的了解,但我很难弄清楚这个错误:

django          | WebSocket HANDSHAKING /ws/events/ [172.19.0.1:49272]
django          | INFO 2021-07-10 12:57:11,000 runserver 11 140153597114112 WebSocket HANDSHAKING /ws/events/ [172.19.0.1:49272]
django          | ERROR 2021-07-10 12:57:12,139 server 11 140153597114112 Exception inside application: [Errno -3] Temporary failure in name resolution
django          | Traceback (most recent call last):
django          |   File "/usr/local/lib/python3.9/site-packages/channels/staticfiles.py", line 44, in __call__
django          |     return await self.application(scope, receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/routing.py", line 71, in __call__
django          |     return await application(scope, receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/sessions.py", line 47, in __call__
django          |     return await self.inner(dict(scope, cookies=cookies), receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/sessions.py", line 254, in __call__
django          |     return await self.inner(wrapper.scope, receive, wrapper.send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/auth.py", line 181, in __call__
django          |     return await super().__call__(scope, receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/middleware.py", line 26, in __call__
django          |     return await self.inner(scope, receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/routing.py", line 150, in __call__
django          |     return await application(
django          |   File "/usr/local/lib/python3.9/site-packages/channels/consumer.py", line 94, in app
django          |     return await consumer(scope, receive, send)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/consumer.py", line 58, in __call__
django          |     await await_many_dispatch(
django          |   File "/usr/local/lib/python3.9/site-packages/channels/utils.py", line 51, in await_many_dispatch
django          |     await dispatch(result)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/consumer.py", line 73, in dispatch
django          |     await handler(message)
django          |   File "/usr/local/lib/python3.9/site-packages/channels/generic/websocket.py", line 175, in websocket_connect
django          |     await self.connect()
django          |   File "/app/twiros/clients/events/consumers.py", line 6, in connect
django          |     await self.channel_layer.group_add('events', self.channel_name)
django          |   File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 645, in group_add
django          |     async with self.connection(self.consistent_hash(group)) as connection:
django          |   File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 909, in __aenter__
django          |     self.conn = await self.pool.pop()
django          |   File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 92, in pop
django          |     conn = await self.create_conn(loop)
django          |   File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 78, in create_conn
django          |     return await aioredis.create_redis_pool(**kwargs)
django          |   File "/usr/local/lib/python3.9/site-packages/aioredis/commands/__init__.py", line 188, in create_redis_pool
django          |     pool = await create_pool(address, db=db,
django          |   File "/usr/local/lib/python3.9/site-packages/aioredis/pool.py", line 58, in create_pool
django          |     await pool._fill_free(override_min=False)
django          |   File "/usr/local/lib/python3.9/site-packages/aioredis/pool.py", line 383, in _fill_free
django          |     conn = await self._create_new_connection(self._address)
django          |   File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 111, in create_connection
django          |     reader, writer = await asyncio.wait_for(open_connection(
django          |   File "/usr/local/lib/python3.9/asyncio/tasks.py", line 442, in wait_for
django          |     return await fut
django          |   File "/usr/local/lib/python3.9/site-packages/aioredis/stream.py", line 23, in open_connection
django          |     transport, _ = await get_event_loop().create_connection(
django          |   File "/usr/local/lib/python3.9/asyncio/base_events.py", line 1017, in create_connection
django          |     infos = await self._ensure_resolved(
django          |   File "/usr/local/lib/python3.9/asyncio/base_events.py", line 1396, in _ensure_resolved
django          |     return await loop.getaddrinfo(host, port, family=family, type=type,
django          |   File "/usr/local/lib/python3.9/asyncio/base_events.py", line 856, in getaddrinfo
django          |     return await self.run_in_executor(
django          |   File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
django          |     result = self.fn(*self.args, **self.kwargs)
django          |   File "/usr/local/lib/python3.9/socket.py", line 953, in getaddrinfo
django          |     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
django          | socket.gaierror: [Errno -3] Temporary failure in name resolution
django          | WebSocket DISCONNECT /ws/events/ [172.19.0.1:49272]
django          | INFO 2021-07-10 12:57:12,148 runserver 11 140153597114112 WebSocket DISCONNECT /ws/events/ [172.19.0.1:49272]

我看到它提到了我的 consumer.py 文件,第 6 行。第 6 行是await self.channel_layer.group_add('events', self.channel_name)

from channels.generic.websocket import AsyncWebsocketConsumer


class EventsConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.channel_layer.group_add('events', self.channel_name)
        await self.accept()

    async def disconnect(self, code):
        await self.channel_layer.group_discard('events', self.channel_name)

    async def send_events(self, event):
        text_message = event['event']

        await self.send(text_message)

我不认为是该文件在名称解析方面有问题,所以我开始进行一些搜索,几乎所有内容都表明这可能是我的 CHANNEL_LAYERS 设置有问题,即:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": ["redis://redis:6379"],
        },
    },
}

redis URL 用于使用 docker-compose 构建的 docker 容器,其相关部分如下:

  redis:
    image: redis:5.0
    container_name: redis

那部分是如此简单,很难相信我搞砸了。

然后我决定在另一端解析 URL 可能是一个错误,所以我检查了用于建立连接的 javascript 代码:

        var socket = new WebSocket('ws://localhost:8000/ws/events/')
        socket.onmessage = function(event){
            var joke = event.data;
            document.querySelector('#jokes').innerText = joke;
        }

它显示路径是/ws/events/. 在我的 asgi.py 中,我有:

application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        "websocket": AuthMiddlewareStack(
            URLRouter(
                ws_urlpatterns,
            )
        ),
    }
)

这是哪里ws_urlpatterns

ws_urlpatterns = [
    path('ws/events/', EventsConsumer.as_asgi())
]

EventsConsumer是我们在上面第 6 行看到的错误,在我分享的第一段代码中。

我没有运气弄清楚我忽略了什么。我将不胜感激任何帮助。

标签: djangoasynchronousdjango-channels

解决方案


嗯,我想通了。对于那些正在使用它的人来说,这个问题是 cookiecutterdjango 的一个小问题。对于本地 docker-composelocal.yml文件production.yml(我假设 redis 已连接,因为如果没有,则拉入图像没有多大用处。不用说,我所要做的就是添加redis到该depends_on部分,它现在可以正常工作了。

django: &django
    build:
      context: .
      dockerfile: ./compose/local/django/Dockerfile
    image: twiros_local_django
    container_name: django
    depends_on:
      - postgres
      - redis
    volumes:
      - .:/app:z
    env_file:
      - ./.envs/.local/.django
      - ./.envs/.local/.postgres
    ports:
      - "8000:8000"
    command: /start

推荐阅读