Django Rest Framework + Django Channels -> [Errno 111] 连接调用失败('127.0.0.1',6379)

问题描述 投票:0回答:1

我正在使用 Django (4.2.6)、Django Rest Framework (3.14.0)、Channels (4.0.0) 和 Channels-Redis(4.2.0) 编写一个项目,它充当移动应用程序的后端。到目前为止,我开发的 Rest API 连接和端点还没有遇到任何问题。我尝试通过 websockets 测试连接,但出现以下错误:

Exception inside application: Error connecting to localhost:6379. Multiple exceptions: [Errno 111] Connect call failed ('::1', 6379, 0, 0), [Errno 111] Connect call failed ('127.0.0.1', 6379).
Traceback (most recent call last):
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/connection.py", line 274, in connect
    await self.retry.call_with_retry(
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/retry.py", line 59, in call_with_retry
    return await do()
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/connection.py", line 681, in _connect
    reader, writer = await asyncio.open_connection(
  File "/usr/lib/python3.10/asyncio/streams.py", line 48, in open_connection
    transport, _ = await loop.create_connection(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 1084, in create_connection
    raise OSError('Multiple exceptions: {}'.format(
OSError: Multiple exceptions: [Errno 111] Connect call failed ('::1', 6379, 0, 0), [Errno 111] Connect call failed ('127.0.0.1', 6379)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/django/contrib/staticfiles/handlers.py", line 101, in __call__
    return await self.application(scope, receive, send)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/routing.py", line 62, in __call__
    return await application(scope, receive, send)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/routing.py", line 116, in __call__
    return await application(
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/consumer.py", line 94, in app
    return await consumer(scope, receive, send)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/consumer.py", line 58, in __call__
    await await_many_dispatch(
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/utils.py", line 50, in await_many_dispatch
    await dispatch(result)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/consumer.py", line 73, in dispatch
    await handler(message)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/djangochannelsrestframework/consumers.py", line 84, in websocket_connect
    await super().websocket_connect(message)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels/generic/websocket.py", line 173, in websocket_connect
    await self.connect()
  File "/home/tecnicus/Documentos/Repositorios/MyProyect/MyApp/api/consumers.py", line 16, in connect
    await self.model_change.subscribe()
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/Selene_Backend_Copy_Test/lib/python3.10/site-packages/djangochannelsrestframework/observer/base_observer.py", line 144, in subscribe
    await consumer.add_group(group_name)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/djangochannelsrestframework/consumers.py", line 102, in add_group
    await self.channel_layer.group_add(name, self.channel_name)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/channels_redis/core.py", line 504, in group_add
    await connection.zadd(group_key, {channel: time.time()})
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/client.py", line 605, in execute_command
    conn = self.connection or await pool.get_connection(command_name, **options)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/connection.py", line 1076, in get_connection
    await self.ensure_connection(connection)
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/connection.py", line 1109, in ensure_connection
    await connection.connect()
  File "/home/tecnicus/Documentos/Repositorios/virtualenvs/virtualenv1/lib/python3.10/site-packages/redis/asyncio/connection.py", line 282, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error connecting to localhost:6379. Multiple exceptions: [Errno 111] Connect call failed ('::1', 6379, 0, 0), [Errno 111] Connect call failed ('127.0.0.1', 6379).
WebSocket DISCONNECT /ws/ [127.0.0.1:33284]


由于我是上述 3 个框架的新手,因此我尝试尽可能遵循它们的文档,以及我找到的相关教程。

设置.py

INSTALLED_APPS = [

    'daphne',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'channels',
    'rest_framework',
    'rest_framework_simplejwt',
    'rest_framework_simplejwt.token_blacklist',
    'djangochannelsrestframework',
    'django_cleanup.apps.CleanupConfig',
    'drf_yasg',
    'django_filters',
    'rangefilter',
    
    # Aplicaciones
    'MyApp',

    
]

ASGI_APPLICATION = 'SeleneServer.asgi.application'


CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [("localhost", 6379)],
        },
    },
}

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication'),
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}

SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(hours=12),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=7),
    'UPDATE_LAST_LOGIN': True
}

Asgi.py


import os
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
import agenda.api.router


os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'SeleneServer.settings')

django_asgi_app = get_asgi_application()

application = ProtocolTypeRouter({
    'http': django_asgi_app,
    'websocket': AuthMiddlewareStack( 
        URLRouter(
            agenda.api.router.websocket_urlpatterns
        )
    )
})

路由器.py


from django.urls import re_path
from MyApp.api.consumers import MyConsumer


websocket_urlpatterns = [
    re_path(r"^ws/", MyConsumer.as_asgi()),
]

消费者.py


from djangochannelsrestframework import permissions
from djangochannelsrestframework.generics import GenericAsyncAPIConsumer
from djangochannelsrestframework.mixins import ListModelMixin
from djangochannelsrestframework.observer import model_observer

from MyApp.models import MyModel
from MyApp.api.serializers import MyModelSerializer

class MyConsumer(ListModelMixin, GenericAsyncAPIConsumer):

    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer
    permissions = (permissions.AllowAny,)

    async def connect(self, **kwargs):
        await self.model_change.subscribe()
        await super().connect()

    @model_observer(MyModel)
    async def model_change(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @model_change.serializer
    def model_serialize(self, instance, action, **kwargs):
        return dict(data=MyModelSerializer(instance=instance).data, action=action.value)


我没有使用 docker 或类似的东西,因为我只想让项目首先在我的计算机上本地运行,然后再将其上传到 Vercel 服务器。


我尝试尝试在没有Daphne的情况下运行该项目,因为我听说对于最新版本的Channels来说,它不是必需的依赖项,但结果是在测试websocket时,服务器抛出了一个错误,指出请求的地址找不到:

Not Found: /ws/      
[05/Mar/2024 02:31:15] "GET /ws/ HTTP/1.1" 404 3003).

我还尝试从 asgi.py 中删除 AuthMiddlewareStack 以测试不需要用户登录的连接,但无论有或没有 daphne,结果都是相同的。

我不知道你是否推荐另一种方法来检查websocket连接,因为我已经使用了Chrome的浏览器WebSocket客户端和python的websocket-client,总是在

ws://127.0.0.1:8000/ws/
,因为前端将在React中开发原生的,还不会开发,但我必须测试 websocket 系统是否可以工作,即使它是非常基础的。

python django django-rest-framework websocket django-channels
1个回答
0
投票

通道需要 REDIS 后端才能运行。需要安装并启动REDIS才能解决错误

© www.soinside.com 2019 - 2024. All rights reserved.