Real time messaging in django using channels

42 Views Asked by At

I am trying to create a Group chat functionality, but my webscoket connection is getting established but messages are sended but not received I have attached my code below please review and let me know solution, I will be very thankful

consumers.py

from channels.generic.websocket import WebsocketConsumer
import json

class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.group_id = self.scope['url_route']['kwargs']['group_id']
        self.group_name = f'chat_{self.group_id}'
        
        # Join  group
        self.accept()
        self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )

    def disconnect(self, close_code):
        # Leave room group
        self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )

    def receive(self, text_data):
        try:
            text_data_json = json.loads(text_data)
            message = text_data_json['message']
            # Send message to room group
            self.channel_layer.group_send(
                self.group_name,
                {
                    'type': 'chat_message',
                    'message': message,
                }
            )
        except json.JSONDecodeError:
            self.send(text_data=json.dumps({
                'error': 'Invalid JSON format.'
            }))
        except Exception as e:
            self.send(text_data=json.dumps({
                'error': str(e)
            }))

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

routing.py

from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.urls import re_path
from . import consumers

websocket_urlpatterns = [
    re_path('ws/(?P<group_id>\w+)/', consumers.ChatConsumer.as_asgi()),
]

application = ProtocolTypeRouter({
    'websocket': AuthMiddlewareStack(
        URLRouter(
            websocket_urlpatterns
        )
    ),
})

asgi.py

import os
import django
from django.conf import settings
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from django.core.asgi import get_asgi_application
from all_pages.routing import websocket_urlpatterns as all_pages_ws_urls
from groupchat.routing import websocket_urlpatterns as groupchat_ws_urls

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nailSent_project.settings')
django.setup()

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            all_pages_ws_urls + groupchat_ws_urls
        )
    )
})

html

{% load static %}
{% block headerContent %}
<link rel="stylesheet" type="text/css" href="{% static 'all_pages/css/chat.css' %}">
{% endblock headerContent %}
{% block mainContent %}
<div class="bg-img">
    <section>
        <div class="container d-flex justify-content-center p-4">
            <div class="card ps-1 pe-1 pt-3 group-chat-card">
                <div class="card-header bg-white">
                    <div class="row">
                        <div class="col-5 d-flex justify-content-start ms-1   ">
                            <img src="https://www.byrdie.com/thmb/0ySp4fK1CSUGg4oTZqlQipGG11I=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/pinknails3-6db6cd98e1224163afbff763fabdf151.jpg"
                                class="group-logo">
                            <div class="pb-0">
                                <h6 class="chat-group-name"><b>Nail Art Group</b></h6>
                                <p class="total-participants">10 Participants</p>
                            </div>

                        </div>
                    </div>
                </div>


                <div class="card-body overflow-y-visible overflow-x-hidden ">
                    <div class="row">
                        <div class="col-12 receiver-box">
                            <div class="row">
                                <div class="col-1 d-flex align-items-end">
                                    <img src="https://www.byrdie.com/thmb/0ySp4fK1CSUGg4oTZqlQipGG11I=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/pinknails3-6db6cd98e1224163afbff763fabdf151.jpg"
                                        class="sender-image">
                                </div>
                                <div class="col-11 ps-3 mb-3">
                                    <div class="ps-2 text-secondary d-block mb-1 text-left"><small>Jackmiller</small>
                                    </div>
                                    <div class="msg-box received-msg receiver-box1">
                                    </div>
                                </div>
                            </div>

                        </div>
                        <div class="col-12 sender-box">
                            <div class="row">
                                <div class="col-11 d-flex align-items-end flex-column ps-3 mb-3">
                                    <div class="ps-2 text-secondary d-block mb-1 text-right"><small>Jackmiller</small>
                                    </div>
                                    <div class="msg-box sent-msg sender-box1">
                                    </div>
                                </div>
                                <div class="col-1 d-flex justify-content-end">
                                    <div class="d-flex justify-content- align-items-end">
                                        <img src="https://www.byrdie.com/thmb/0ySp4fK1CSUGg4oTZqlQipGG11I=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/pinknails3-6db6cd98e1224163afbff763fabdf151.jpg"
                                            class="receiver-image">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="card-footer">
                    <div class="send-input m-3 d-flex align-items-center">
                        <div class="textarea-wrapper flex-grow-1 me-2">
                            <input class="form-control scroll" placeholder="Enter your message..." id="sendMessageInput"
                                type="text" />
                        </div>
                        <button id="sendButton" type="button" class="btn snd-btn">
                            <img src="{% static 'all_pages/images/icons/sendbtn.png'%}" height="20" width="20"
                                alt="Send Button" class="snd-btn">
                        </button>
                    </div>
                </div>

            </div>
        </div>
    </section>
</div>
<script>
    const receiverBox = document.querySelector('.receiver-box1');
    const senderBox = document.querySelector('.sender-box1');

    function appendReceivedMessage(message) {
        const messageElement = document.createElement('p');
        messageElement.textContent = message;
        receiverBox.appendChild(messageElement);
    }

    const chatBody = document.getElementById('chatBody');
    const sendMessageInput = document.getElementById('sendMessageInput');
    const sendButton = document.getElementById('sendButton');
    const group_id = "{{ group_id }}";

    const chatSocket = new WebSocket(
        'ws://' + window.location.hostname + ':8000' +
        '/ws/' + group_id + '/'
    );

    chatSocket.onopen = function(event) {
        console.log('WebSocket connection established.');
    };

    chatSocket.onmessage = function(event) {
        const data = JSON.parse(event.data);
        console.log('Message received from server:', event);
        appendReceivedMessage(data.message);
    };

    sendButton.addEventListener('click', sendMessage);

    function sendMessage() {
        const message = sendMessageInput.value.trim();
        if (message !== '') {
            let messageElement1 = document.createElement('p');
            messageElement1.textContent = message;
            senderBox.appendChild(messageElement1);
            chatSocket.send(JSON.stringify({
                'message': message
            }));
            sendMessageInput.value = '';
        }
    }
</script>


{% endblock mainContent %}

models

from django.db import models
from users.models import User
from special_events.models import Group
# Create your models here.
class Message(models.Model):
    group = models.ForeignKey(Group, related_name='messages', on_delete=models.CASCADE)
    sender = models.ForeignKey(User, related_name='sent_messages', on_delete=models.CASCADE)
    content = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)
    created_at =  models.DateField(auto_now_add=True)
    class Meta:
        ordering = ('created_at',)

    def __str__(self):
        return f'{self.sender}'


class Group(models.Model):
    name = models.ForeignKey(SpecialEvent, related_name='group_name', on_delete=models.CASCADE, null=True)
    admins = models.ManyToManyField(User, related_name='admin_groups')
    participants = models.ManyToManyField(User, related_name='participating_groups')

please review the above code and provide me some solution

0

There are 0 best solutions below