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.
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.