6
votes

django-channels: Aucune route trouvée pour le chemin

J'ai une application de chat Django + Vue.js que j'essaie de connecter aux canaux django.

Pour accéder à n'importe quelle salle de chat, il suffit d'aller sur:

http: // localhost: 8080 / rooms / "id" /

Ma connexion javascript ressemble à ceci:

from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter

import core.routing


application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            core.routing.websocket_urlpatterns
        )
    )
})

Mes consommateurs.py:

from django.conf.urls import url

from core import consumers


websocket_urlpatterns = [
    url(r'^ws/rooms/<uri>/', consumers.ChatConsumer),
]

et mon routing.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
    }))

mon projet routing.py:

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
},

Le problème est que je n'arrive pas à me connecter au websocket, mon serveur django dit:

[Instance d'échec: Traceback:: Aucune route trouvée pour le chemin 'ws / rooms / 759b9a8262ea4b7 /'.

Quel est le problème dans mon code et que je ne peux pas me connecter à une salle spécifique via le websocket?

Trace complète de la pile:

[Instance d'échec: Traceback:: Aucune route trouvée pour le chemin '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: /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:appel


5 commentaires

Vous utilisez Django urls aka re_path Je vous suggère de donner une expression régulière appropriée à votre urlpattern. Peut être ça? url (r '^ ws / rooms / (? P \ d +) /', consumer.ChatConsumer) ,


@RajaSimon merci, mais j'obtiens toujours la même erreur


Pouvez-vous publier votre projet routing.py?


@RajaSimon Je l'ai ajouté à ma question


Cela devrait fonctionner avec votre configuration. r '^ ws / rooms / (? P [^ /] +) / $' Je ne vois aucune autre raison pour laquelle cela ne fonctionne pas.


3 Réponses :


1
votes

Essayez quelque chose comme ceci:

routing.py (dans votre application django)

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [REDIS_URL],
        },
    },
}

INSTALLED_APPS.append('channels')
ASGI_APPLICATION = 'myapp.routing.application'

routing.py (même niveau que votre settings.py) p >

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
        )
    ),
})

Et enfin dans vos paramètres.py

from django.urls import path
from core import consumers

websocket_urlpatterns = [
    path('ws/rooms/<uri>/', consumers.ChatConsumer),
]


6 commentaires

Pouvez-vous s'il vous plaît envoyer la trace complète de la pile?


J'ai ajouté ceci au message d'origine


J'ai modifié ma réponse après avoir testé l'URL - Cela résout définitivement, le problème peut être que vous manquez du code dans vos paramètres ou que vous manquez le premier fichier de routage qui est censé vivre au même niveau que le < code> settings.py


J'ai fait tout cela avant, c'est exactement comme dans votre réponse. Mon problème peut-il dépendre de consumer.py?


Vous pouvez spécifier le type de l'url kwarg comme ce chemin ('ws / rooms / /', consumer.ChatConsumer)


@desiiner. Vous pouvez essayer de voir si les consommateurs posent un problème en supprimant tout le code de la fonction de connexion et en laissant simplement la ligne self.accept. Parfois, ce n'est pas très bavard avec où se situe le problème



4
votes

J'ai rencontré le même problème que vous, et je viens de le résoudre! dans mon ws_client.py j'ai écrit ceci

from django.urls import path
channel_routing = [
    path('alarm',consumers.ws_message),
    # before I wrote 'alarm/', I just change from alarm/ to alarm
]

et dans routing.py j'ai changé pour ceci ci-dessous et cela a fonctionné

ws.create_connection("ws://127.0.0.1:8000/alarm")

et cela a fonctionné ! vous pouvez l'essayer


0 commentaires

8
votes

Vous devez utiliser url , j'ai eu le même problème:

ne fonctionne pas

websocket_urlpatterns = [
   url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
]

fonctionne

websocket_urlpatterns = [
  path('ws/chat/<str:room_name>/$', consumers.ChatConsumer),
]


2 commentaires

Résout le problème du didacticiel Channels 2.0


le chemin doit être utilisé sans la fin de $ (l'url utilise des expressions régulières, le chemin utilise sa propre syntaxe simplifiée)