0

I am not using this Django channels for chat purpose, I am connecting the user through web socket via DRF AUTH token

var ws = new WebSocket("ws://127.0.0.1:8008/ws/stream/<token>/")

I want to achieve if the admin delete the User from backend then in mobile front end I will get the automatically response that user is deleted and then I will call the disconnect method, which will logout the user in front end for that below code I am using. But unable to send message from outside of consumer. Here below is my code:-

class Consumer(AsyncJsonWebsocketConsumer):
    """
    This chat consumer handles websocket connections for chat clients.

    It uses AsyncJsonWebsocketConsumer, which means all the handling functions
    must be async functions, and any sync work (like ORM access) has to be
    behind database_sync_to_async or sync_to_async. For more, read
    http://channels.readthedocs.io/en/latest/topics/consumers.html
    """

    ##### WebSocket event handlers

    async def connect(self):
        """
        Called when the websocket is handshaking as part of initial connection.
        """
        # query_string = dict(self.scope).get('query_string')
        # keys = dict(parse.parse_qs(query_string.decode()))
        self.token_key = self.scope['url_route']['kwargs']['token']
        try:
            if self.token_key:
                # access_token = keys.get('key')
                print(self.token_key)
                self.scope['user'] = await get_user(self.token_key)
                # self.chat_room = self.scope['url_route']['kwargs']['channel']
                await self.accept()
                await self.send_json({'code':200, 'message': 'Connection establish successfully', 'error_message': '', 'data':{}})

        except Exception as ex:
            print("Exception", ex)
            self.scope['user'] = AnonymousUser()
            await self.close()
        

    async def receive_json(self, content):
        """
        Called when we get a text frame. Channels will JSON-decode the payload
        for us and pass it as the first argument.
        """
        # Messages will have a "command" key we can switch on
        try:
            print("this is the content",content)
            command = content.get("command", None)
            #  Under construction

        except ClientError as e:
            # Catch any errors and send it back
            await self.send_json({"error": e.code})

    async def user_delete(self):
        await self.send_json({'code':400, 'message': 'User deleted', 'error_message': '', 'data':{}})

    async def disconnect(self, code):
        """
        Called when the WebSocket closes for any reason.
        """
        # Leave all the rooms we are still in
        await self.close()

and below code for django models (using Signals call when delete operation performed)

from channels.layers import get_channel_layer
class Profile(models.Model):
       ......
       ......
@receiver(post_delete, sender=Profile)
def s3_delete(sender, instance, using, **kwargs):
    try:
        channel_layer = get_channel_layer()
        ?????
        channel_layer.send_json({'user deleted'})     #Solution which i am trying to apply

    except Exception as ex:
        msg = str(ex)
        print(msg)  

Note: Reference which I Used: Send message using Django Channels from outside Consumer class

davidism
  • 121,510
  • 29
  • 395
  • 339

1 Answers1

1

Hello this is my solution, first change somethings in your consumer. device_info method is just a example you can add anything.

class Consumer(WebsocketConsumer):

    def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'something_%s' % self.room_name
        async_to_sync(self.channel_layer.group_add)(
            self.room_group_name,
            self.channel_name
        )
        self.accept()

   def device_info(self, event):
        message = event['message']
        self.send(text_data=json.dumps({
            'message': message
        }))

   ***other staff u wanna to add

this is my channel urls file.

from django.conf.urls import re_path
from <app_name>.consumer import Consumer

websocket_urlpatterns = [
    re_path(r'url/to/channel/(?P<room_name>\w+)/$', Consumer),
]

and here is the code that i send whatever i want to channels.

from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync

room_name = 'outside'

channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(f"something_{room_name}", {"type": "device_info", "message": dict(key="json data that u wanna send outside of consumer")})
Dad
  • 377
  • 2
  • 8