zoukankan      html  css  js  c++  java
  • Channels集成到Django消息实时推送

    channel架构图

    InterFace Server:负责对协议进行解析,将不同的协议分发到不同的Channel

    Channel Layer:频道层,可以是一个FIFO队列,通常使用Redis

    Django中配置Channel:

    CHANNEL_LAYERS的配置:

    CHANNEL_LAYERS = {
        "default": {
            "BACKEND": "channels_redis.core.RedisChannelLayer",
            "CONFIG": {
                "hosts": ["redis://127.0.0.1:6379", ], 
            },
        },
    }

    asgi的配置:

    import os
    import sys
    import django
    from channels.routing import get_default_application
    
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "web.settings_local")
    django.setup()
    application = get_default_application()

    consumers代码:

    class NotificationsConsumer(AsyncWebsocketConsumer):
        """处理通知应用中的WebSocket请求"""
    
        async def connect(self):
            """建立连接"""
            if self.scope['user'].is_anonymous:
                # 未登录用户拒绝连接
                await self.close()
            else:
                await self.channel_layer.group_add(
                    'notifications', self.channel_name
                )
                await self.accept()
    
        async def receive(self, text_data=None, bytes_data=None):
            """将接收到的消息返回给前端"""
            await self.send(text_data=json.dumps(text_data))
    
        async def disconnect(self, code):
            """断开连接"""
            await self.channel_layer.group_discard(
                'notifications', self.channel_name
            )

     channels将同步的MySQL转换为异步的:

    # ORM语句同步变异步,方式一
    from channels.db import database_sync_to_async
    user = await database_sync_to_async(User.objects.get(username=username))
    
    # ORM语句同步变异步,方式二
    @database_sync_to_async
    def get_username(username):
        return User.objects.get(username=username)
    

    配置routing:

    from django.urls import path
    from channels.auth import AuthMiddlewareStack  # channels的认证中间件
    from channels.routing import ProtocolTypeRouter, URLRouter
    from channels.security.websocket import AllowedHostsOriginValidator
    
    from notifications.consumers import NotificationsConsumer
    
    
    application = ProtocolTypeRouter({
        'websocket': AllowedHostsOriginValidator(
            AuthMiddlewareStack(
                URLRouter([
                    path('ws/notifications/', NotificationsConsumer),
                ])
            )
        )
    })
    

    settings中配置:

    INSTALLED_APPS中加入:

    'channels',

    配置ASGI_APPLICATION:
    ASGI_APPLICATION = 'web.routing.application'

    notifications 业务层实现逻辑:

    channel_layer = get_channel_layer()
    payload = {
        'type': 'receive',
        'key': key,
        'actor_name': actor.username,
        'id_value': id_value
    }
    async_to_sync(channel_layer.group_send)('notifications', payload)
    

    消息通知业务流程:
    用户触发了消息 --> Django的view层 --> 保存到MySQL数据库 --> 将消息通知发送到channel对应的group里面 --> websocket将消息通过consumer推送给接收方

  • 相关阅读:
    人名币转大写
    Http协议与TCP协议简单理解
    unity3d常用属性汇总
    ConcurrentHashMap的key value不能为null,map可以?
    一个线程池中的线程异常了,那么线程池会怎么处理这个线程?
    Dubbo负载均衡算法
    [LeetCode] 240. 搜索二维矩阵 II ☆☆☆(二分查找类似)
    [LeetCode] 74. 搜索二维矩阵 ☆☆☆(二分查找)
    Maven中的dependencyManagement 意义
    深入理解maven构建生命周期和各种plugin插件
  • 原文地址:https://www.cnblogs.com/FG123/p/10909244.html
Copyright © 2011-2022 走看看