I am programming a project with Django (4.2.6), Django Rest Framework (3.14.0), Channels (4.0.0) and Channels-Redis(4.2.0), which acts as a backend for a mobile application. So far, I haven't had any problems with the Rest API connections and the endpoints I developed. I try to test the connection through websockets, but I get the following error:
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]
As I am a newbie when it comes to the 3 frameworks mentioned, I tried to follow the documentation of them as best I could, plus the tutorials that I found about it.
Settings.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
)
)
})
Router.py
from django.urls import re_path
from MyApp.api.consumers import MyConsumer
websocket_urlpatterns = [
re_path(r"^ws/", MyConsumer.as_asgi()),
]
Consumers.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)
I am not using docker or anything similar, since I only want the project to work locally on my computer first, before uploading it to the Vercel server.
I tried to try running the project without Daphne, because I heard that for the latest versions of Channels it was not a required dependency, but the result was that when testing the websocket, the server threw an error that the address to which the request was made cannot be found:
Not Found: /ws/
[05/Mar/2024 02:31:15] "GET /ws/ HTTP/1.1" 404 3003).
I also tried to remove the AuthMiddlewareStack from asgi.py to test a connection that does not require the user to be logged in, but the results are the same, with or without daphne.
I don't know if you recommend another way to check the websocket connection, since I have used Browser WebSocket Client for Chrome, and websocket-client for python, always at ws://127.0.0.1:8000/ws/
, since the frontend, which will be developed in React Native and will not be developed yet, but I must test if the websocket system will work, even if it is at a very basic.
Channels need a REDIS backend to be able to operate. You need to install and start REDIS to solve the error