Reputation: 2316
I have a Django + Vue.js chat application that I'm trying to connect to django-channels.
To access any chat room, you simply go to:
My javascript connection looks like this:
connectToWebSocket () {
const chatSocket = new WebSocket(
`ws://localhost:8000/ws/rooms/${this.$route.params.id}/`
)
chatSocket.onopen = this.onOpen
chatSocket.onclose = this.onClose
chatSocket.onmessage = this.onMessage
chatSocket.onerror = this.onError
},
My consumers.py:
class ChatConsumer(WebsocketConsumer):
def connect(self):
self.room_uri = self.scope['url_route']['kwargs']['uri']
self.room_group_name = 'chat_%s' % self.room_uri
# 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']
user = text_data_json['user.username']
# Send message to room group
async_to_sync(self.channel_layer.group_send)(
self.room_group_name,
{
'type': 'chat_message',
'user': user,
'message': message
}
)
# Receive message from room group
def chat_message(self, event):
user = event['user']
message = event['message']
# Send message to WebSocket
self.send(text_data=json.dumps({
'user': user,
'message': message
}))
and my routing.py:
from django.conf.urls import url
from core import consumers
websocket_urlpatterns = [
url(r'^ws/rooms/<uri>/', consumers.ChatConsumer),
]
my project routing.py:
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import core.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
core.routing.websocket_urlpatterns
)
)
})
The problem is, I can't connect to the websocket, my django server says:
[Failure instance: Traceback: : No route found for path 'ws/rooms/759b9a8262ea4b7/'.
What's wrong in my code that I can't connect to a specific room through the websocket?
Full stack trace:
[Failure instance: Traceback: : No route found for path 'ws/rooms/759b9a8262ea4b7/'. /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/autobahn/websocket/protocol.py:2801:processHandshake /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/txaio/tx.py:429:as_future /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/twisted/internet/defer.py:151:maybeDeferred /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/daphne/ws_protocol.py:82:onConnect --- --- /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/twisted/internet/defer.py:151:maybeDeferred /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/daphne/server.py:198:create_application /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/staticfiles.py:41:call /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/routing.py:58:call /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/sessions.py:43:call /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/sessions.py:141:call /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/sessions.py:165:init /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/middleware.py:31:call /home/dave/PycharmProjects/chatapp2/back/venv/lib/python3.6/site-packages/channels/routing.py:154:call
Upvotes: 16
Views: 29360
Reputation: 335
If anyone is facing this issue, check the trailing slashes in the url in your JavaScript or in the websocket_urlpatterns. Make sure they're the same.
Upvotes: 0
Reputation: 109
I spent like more than an hour to this problem and I found out that django project my default doesn't take asgi.py configuration settings in consideration.
Install daphne into your project
python -m pip install daphne
list into your INSTALLED_APPS
array
INSTALLED_APPS = [
"daphne",
...,
]
ASGI_APPLICATION = "myproject.asgi.application"
Run your project and see if it connects with your websocket.
For context, my asgi.py file is like this
import os
from django.core.asgi import get_asgi_application
from django.urls import path
from channels.routing import ProtocolTypeRouter, URLRouter
from chat_app.routing import ChatConsumer
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'teacher_gpt_chat.settings')
websocket_urlpatterns = [
path('ws/chat', ChatConsumer.as_asgi())
]
application = ProtocolTypeRouter(
{
"http": get_asgi_application(),
"websocket": URLRouter(websocket_urlpatterns),
}
)
Upvotes: 1
Reputation: 1289
Try something like this:
routing.py (Inside your django app folder)
from django.urls import path
from core import consumers
websocket_urlpatterns = [
path('ws/rooms/<uri>/', consumers.ChatConsumer),
]
routing.py (Same level as your settings.py)
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import myapp.routing
application = ProtocolTypeRouter({
# (http->django views is added by default)
'websocket': AuthMiddlewareStack(
URLRouter(
myapp.routing.websocket_urlpatterns
)
),
})
And lastly in your settings.py
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [REDIS_URL],
},
},
}
INSTALLED_APPS.append('channels')
ASGI_APPLICATION = 'myapp.routing.application'
Upvotes: 8
Reputation: 1
you may need to restart the services, seems it would not automatic reload.
Upvotes: 0
Reputation: 788
To anyone new that may be facing this issue. Don't use the path
pattern matcher with a regular expression. If you wish to do use, use either url
or re_path
instead.
using path
Match pattern without trailing or leading slash (/) and make sure pattern corresponds with client web socket URL
websocket_urlpatterns = [
path("ws/chat/<int:uri>", ChatConsumer.as_asgi()),
]
Using re_path
or url
Match pattern without trailing slash (/).
url(r'^ws/chat/(?P<uri>[^/]+)/$', ChatConsumer.as_asgi()),
NOTE: I advise using path
because it's easier to match patterns and read.
Upvotes: 2
Reputation: 39
i had similar issue and added .as_asgi() and it worked
url(r"messages/(?P<username>[\w.@+-]+)/", ChatConsumer.as_asgi())
,
Upvotes: 0
Reputation: 1054
Removing the slash from the app.routing routes file solved the problem, I guess it was being counted a duplicate slash in the URL of that socket.
For instance, I had:
url(r'/ws/documents/get-df', consumers.DFConsumer.as_asgi())
This was not working, but it worked when I removed the first slash before was
url(r'ws/documents/get-df', consumers.DFConsumer.as_asgi())
Upvotes: 1
Reputation: 151
You need to use url
, I had the same problem:
websocket_urlpatterns = [
path('ws/chat/<str:room_name>/$', consumers.ChatConsumer),
]
websocket_urlpatterns = [
url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
]
Upvotes: 15
Reputation: 71
I met the same problem as you,and just now I happened to solve it! in my ws_client.py I wrote this
ws.create_connection("ws://127.0.0.1:8000/alarm")
and in routing.py I changed to this below and it worked
from django.urls import path
channel_routing = [
path('alarm',consumers.ws_message),
# before I wrote 'alarm/', I just change from alarm/ to alarm
]
and it worked! you can try it
Upvotes: 6