简体   繁体   English

如何从 Django 频道中的消费者类外部发送正常的 JSON 消息

[英]How to send normal JSON message from outside of consumer class in django channels

I am not using this Django channels for chat purpose, I am connecting the user through web socket via DRF AUTH token我没有将此 Django 频道用于聊天目的,而是通过 DRF AUTH 令牌通过网络套接字连接用户

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)和下面的 django 模型代码(执行删除操作时使用 Signals 调用)

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注意:我使用的参考: 使用来自外部 Consumer 类的 Django Channels 发送消息

Hello this is my solution, first change somethings in your consumer.你好,这是我的解决方案,首先在你的消费者中改变一些东西。 device_info method is just a example you can add anything. device_info方法只是一个示例,您可以添加任何内容。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM