【问题标题】:How to send normal JSON message from outside of consumer class in django channels如何在 django 频道中从消费者类外部发送普通 JSON 消息
【发布时间】:2020-10-29 15:58:18
【问题描述】:

我没有使用这个 Django 频道进行聊天,我通过网络套接字通过 DRF AUTH 令牌连接用户

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

我想实现如果管理员从后端删除用户,那么在移动前端我会得到用户被删除的自动响应,然后我会调用断开连接方法,这将注销前端的用户,如下所示我正在使用的代码。但无法从消费者外部发送消息。 下面是我的代码:-

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()

及以下django模型的代码(执行删除操作时使用信号调用)

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)  

注意:我使用的参考: Send message using Django Channels from outside Consumer class

【问题讨论】:

    标签: python django flask websocket django-channels


    【解决方案1】:

    您好,这是我的解决方案, 首先改变你的消费者的一些东西。 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
    
    

    这是我的频道网址文件。

    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),
    ]
    
    

    这是我发送任何我想要的频道的代码。

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

    【讨论】:

      猜你喜欢
      • 2022-09-27
      • 2022-08-09
      • 2018-08-20
      • 1970-01-01
      • 2020-05-13
      • 2020-07-16
      • 1970-01-01
      • 2019-06-24
      • 1970-01-01
      相关资源
      最近更新 更多