Search code examples
javascriptdjangowebsocketdjango-templatesdjango-channels

Django Channels error when trying to create a web-socket connection ValueError: No route found for path ' '


I am working on a Django chat application using django-channels and websockets. I have been following a tutorial whereby the instructor is creating a one-to-one chat between two users. In his example, the instructor is using the URLRouter but I have used the websocketurlpatterns. the error I am getting states ValueError: No route found for path 'ws/chat/' and the websocket connection is not established. Here is my consumers.py:

class ChatConsumer(SyncConsumer):
def websocket_connect(self, event):
me = self.scope\['user'\]
other_username = self.scope\['url_route'\]\['kwargs'\]\['username'\]
other_user = User.objects.get(username=other_username)
self.thread_obj = Thread.objects.get_or_create_personal_thread(me, other_user)
self.room_name = f'presonal_thread\_{self.thread_obj.id}'
async_to_sync(self.channel_layer.group_add)(self.room_name, self.channel_name)
self.send({
'type': 'websocket.accept'
})
print(f'\[{self.channel_name}\] - You are connected')

    def websocket_receive(self, event):
        print(f'[{self.channel_name}] - Recieved message - {event["text"]}')
    
        msg = json.dumps({
            'text': event.get('text'),
            'username': self.scope['user'].username
        })
    
        self.store_message(event.get('text'))
    
        async_to_sync(self.channel_layer.group_send)(
            self.room_name,
             {
                'type': 'websocket.message',
                'text': msg
             }
        )
    
    def websocket_message(self, event):
        print(f'[{self.channel_name}] - Message sent - {event["text"]}')
        self.send({
            'type': 'websocket.send',
            'text': event.get('text')
        })
    
    def websocket_disconnect(self, event):
        print(f'[{self.channel_name}] - Disonnected')
        async_to_sync(self.channel_layer.group_discard)(self.room_name, self.channel_name)
    
    def store_message(self, text):
        Message.objects.create(
            thread = self.thread_obj,
            sender = self.scope['user'],
            text = text
        )

class EchoConsumer(SyncConsumer):
def websocket_connect(self, event):
self.room_name = 'broadcast'
self.send({
'type': 'websocket.accept'
})
async_to_sync(self.channel_layer.group_add)(self.room_name, self.channel_name)
print(f'\[{self.channel_name}\] - You are connected')

    def websocket_receive(self, event):
        print(f'[{self.channel_name}] - Recieved message - {event["text"]}')
        async_to_sync(self.channel_layer.group_send)(
            self.room_name,
             {
                'type': 'websocket.message',
                'text': event.get('text')
             }
        )
    
    def websocket_message(self, event):
        print(f'[{self.channel_name}] - Message sent - {event["text"]}')
        self.send({
            'type': 'websocket.send',
            'text': event.get('text')
        })
    
    def websocket_disconnect(self, event):
        print(f'[{self.channel_name}] - Disonnected')
        async_to_sync(self.channel_layer.group_discard)(self.room_name, self.channel_name)

And here is the urls.py:

urlpatterns = \[
path('\<str:username\>/', ThreadView.as_view(), name= 'chat'),
\]

And then here is my routing.py:

websocket_urlpatterns = [
    re_path(r"ws/chat/(?P<username>\w+)/$", consumers.ChatConsumer.as_asgi()),
    # re_path(r"ws/chat/$", consumers.EchoConsumer.as_asgi()),
]

In the routing, whenever I use the EchoConsumer, the websocket connection is happening. So I think the problem is caused by the username, but I cannot figure out how to solve it. Also attached here is the template containing the websocket:

<script>
    
    const url = 'ws://localhost:8000/ws/chat/';
    // const url = 'ws://' + window.location.host + '/ws/chat/' + username + '/';
    // const url = 'ws://localhost:8000/ws' + window.location.pathname;
    const ws = new WebSocket(url) 

    ws.onopen = function(event) {
        console.log("Connection is opened");
        ws.send("Thanks for connecting");
    }

    ws.onmessage = function(event) {
        console.log(event);
        console.log("Message is received");
        const ul = document.getElementById('message-list');
        var li = document.createElement('li');
        // var data = JSON.parse(event.data);
        var data = event.data;
        
        li.append(document.createTextNode(
            '[' + data.username + ']:' + data
        ));
        ul.append(li);
    }

    ws.onclose = function(event) {
        console.log("Connection is closed");
    }

    ws.onerror = function(event) {
        console.log("Something went wrong");
    }

    const messageForm = document.getElementById('message-form')
    messageForm.addEventListener('submit', sendMessage)
    function sendMessage(e) {
        if (e.preventDefault) e.preventDefault();
        ws.send(document.getElementById('message').value);
        messageForm.reset()
        return false;
    }
</script>

I have tried changing the URL in the script as indicated by the commented lines. Any assistance will be highly appreciated. Thank you.

I have tried changing the URL pattern in the javascript but it does not help either.


Solution

  • So I finally found the solution to this problem. It has emerged that for the url to work, I have to use localhost:8000 instead of using 127.0.0.1:8000 in the url of the browser. This way, the websocket managed to function perfectly. Thank you all.