'Django WebSocket DISCONNECT /ws/chat/lobby/ [127.0.0.1:3022]
i want to create chat app, i follow the https://channels.readthedocs.io/en/latest/tutorial/part_2.html here,
chat/
__init__.py
routing.py
urls.py
settings.py
wsgi.py
i added this code to my routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
chat.routing.websocket_urlpatterns
)
),
})
in my settings.py
ASGI_APPLICATION = 'Accounting.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
in my urls.py
urlpatterns = [
path('chat/', include('chat.urls')),
path('admin/', admin.site.urls),
]
in my chat app
chat/
__init__.py
consumers.py
routing.py
templates/
chat/
index.html
room.html
urls.py
views.py
i have consumers.py
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
import json
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_name = self.scope['url_route']['kwargs']['room_name']
self.room_group_name = 'chat_%s' % self.room_name
# Join room group
async_to_sync(self.channel_layer.group_add)(
self.room_group_name,
self.channel_name
)
self.accept()
def disconnect(self, close_code):
# Leave room group
async_to_sync(self.channel_layer.group_discard)(
self.room_group_name,
self.channel_name
)
# Receive message from WebSocket
def receive(self, text_data):
text_data_json = json.loads(text_data)
message = text_data_json['message']
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'message': message
}
)
# Receive message from room group
def chat_message(self, event):
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'message': message
}))
this is the code in my chat>routing.py
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer),
]
in my chat>views.py
from django.shortcuts import render
def index(request):
return render(request, 'chat/index.html', {})
def room(request, room_name):
return render(request, 'chat/room.html', {
'room_name': room_name
})
i have urls.py in my chat app
from django.urls import path
from . import views
app_name = 'chat'
urlpatterns = [
path('', views.index, name='index'),
path('<str:room_name>/', views.room, name='room'),
]
i follow all the direction, i copy paste the code, the placement of py, everything in the turorial, but still i get this error
did i miss something?
UPDATE
when i tried this in my pycharm terminal docker run -p 6379:6379 -d redis:2.8
Solution 1:[1]
a few things have issues here.
1) you are mixing async
and sync
consumer code.
I suggest just using the async consumer
all you methods then should be async
methods.
It looks like you are calling get_thread
from a sync context but get_thread
has been wrapped in database_sync_to_async
so needs to be Called from an async context (and needs to be awaited).
you also need to await
self.channel_layer.group_add
2) in your ThreadView
you have a ChatMessage.objects.create
here you should also send a message over the thread channel group.
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(f"thread_{thread.id}", {"type": "chat.message", "text": ...})
you also need to save the Chat message to the DB in your websocket_receive.
Solution 2:[2]
I think in your settings.py
file a template variable called CHANNEL_LAYER
is enabled (that is the exact cause of the error), so try to remove this piece of code from project/settings.py
CHANNEL_LAYERS = {
'default': {
'BACKEND': '',
'CONFIG': {
"hosts":[127.0.0.1],
},
},
}
In my case it was the root cause of the error. If it doesn't work try to change your chat/routing.py file.
Solution 3:[3]
ADD ".as_asgi()"
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/chat/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()),
]
Solution 4:[4]
I got into the same problem, its the server disconnected issue and that causes all these. https://github.com/tporadowski/redis/releases/tag/v5.0.9 Download the latest version and run the redis-server application. It solved my problem
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Matthaus Woolard |
Solution 2 | buddemat |
Solution 3 | Vladimir Baranov |
Solution 4 | Agnishwar Art |