如何从Django通道中的消费者类外部发送普通JSON消息

时间:2020-10-29 15:58:18

标签: python django flask websocket django-channels

我没有将此Django频道用于聊天目的,而是通过DRF AUTH令牌通过Web套接字连接用户

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

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

1 个答案:

答案 0 :(得分:0)

您好,这是我的解决方法, 首先改变您的消费者的东西。 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")})
相关问题