• Django 项目使用websocket


    django 项目配置websocket

    1.安装包

    channels==3.0.4
    channels-redis==3.3.1
    

      

    2.修改项目配置文件settings.py

    INSTALLED_APPS = [
        'simpleui',
        'corsheaders',
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app.apps.AppConfig',
        'rest_framework',
        'django_filters',
        'channels',
        'channels_redis',
    ]

    ASGI_APPLICATION = "项目名称.routing.application"  # 上面新建的 asgi 应用

    WSGI_APPLICATION = '项目名称.wsgi.application'

    CHANNEL_LAYERS = {
    'default': {
    # 这里用到了 channels_redis
    'BACKEND': 'channels_redis.core.RedisChannelLayer',
    'CONFIG': {
    'hosts': [(cf.get("redis", "LOCATION"), cf.get("redis", "REDISPORT"))], # 配置你自己的 redis 服务信息
    },
    }
    }
    
    
    # redis配置
    CACHES = {
    "default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://{}:{}".format(cf.get("redis", "LOCATION"), cf.get("redis", "REDISPORT")),
    "OPTIONS": {
    "CLIENT_CLASS": "django_redis.client.DefaultClient",
    "CONNECTION_POOL_KWARGS": {"max_connections": 100}
    # "PASSWORD": "密码",
    }
    }
    }
     

    3.项目目录下新建  > routing.py

    from channels.auth import AuthMiddlewareStack
    from channels.routing import ProtocolTypeRouter, URLRouter
    
    import app.routing
    
    application = ProtocolTypeRouter({
        # (http->django views is added by default)
        # 普通的HTTP请求不需要我们手动在这里添加,框架会自动加载过来
        'websocket': AuthMiddlewareStack(
            URLRouter(
                app.routing.websocket_urlpatterns
            )
        ),
    })

    项目目录下新建  > pro_asgi.py  (django 通过uwsig 启动需要用到, 本地开发环境可以不用)

    生产环境启动命令
    nohup daphne -b 0.0.0.0 -p 9011 项目名称.pro_asgi:application
    """
    ASGI config for SOWebOffice project.
    
    It exposes the ASGI callable as a module-level variable named ``application``.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
    """
    
    import os
    
    #from django.core.asgi import get_asgi_application
    import django
    from channels.routing import get_default_application
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'SOSendMessage.settings')
    django.setup()
    application = get_default_application()

    4.项目 app 目录下新建  > consumers.py

    import json, uuid
    import datetime
    import time
    from asgiref.sync import async_to_sync
    import multiprocessing
    from channels.generic.websocket import WebsocketConsumer
    from rest_framework_jwt.settings import api_settings
    from django.contrib.auth.models import Permission, User
    from django.core.cache import cache  # 引入缓存模块
    
    
    class ChatConsumer(WebsocketConsumer):
    
        def connect(self):
            print("connect")
            # 当 websocket 一链接上以后触发该函数
            try:
                dataDict = str(self.scope["query_string"], encoding='utf-8').split("&")
                token = dataDict[0].replace("token=", "")
                jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
                user_dict = jwt_decode_handler(token)
                print("user_dict===>", user_dict)
                cuser = User.objects.filter(username=str(user_dict["username"])).first()
                self.user = cuser
                self.room_group_name = str(cuser.email).split('@')[0]  # 'chat_%s' % str(self.scope["query_string"], encoding='utf-8').split("=")[1]
                print("room_group_name=======>", self.room_group_name)
                # 注意 `group_add` 只支持异步调用,所以这里需要使用`async_to_sync`转换为同步调用
                async_to_sync(self.channel_layer.group_add)(
                    self.room_group_name,
                    self.channel_name
                )
                # 接受该链接
                self.accept()
            except Exception as ex:
                print("Exception=============>", ex.args)
    
        def disconnect(self, close_code):
            # 断开链接是触发该函数
            # 将该链接移出聊天室
            async_to_sync(self.channel_layer.group_discard)(
                self.room_group_name,
                self.channel_name
            )
    
        def receive(self, text_data):
            # 前端发送来消息时,通过这个接口传递
            # text_data_json = json.loads(text_data)
            # message = text_data_json['message']
            async_to_sync(self.channel_layer.group_send)(
                self.room_group_name,
                {
                    # 这里的type要在当前类中实现一个相应的函数,
                    # 下划线或者'.'的都会被Channels转换为下划线处理,
                    # 所以这里写 'chat.message'也没问题
                    'type': 'chat_message',
                    'message': text_data
                }
            )
    
        def chat_message(self, event):
            message = event['message']
    
            # Send message to WebSocket
            self.send(text_data=json.dumps({
                'message': message
            }))

    5.项目 app 目录下新建  > routing.py

    from django.urls import path
    
    from app.consumers import ChatConsumer
    
    websocket_urlpatterns = [
        # 消息推送socket
        path('somessws/chat/', ChatConsumer.as_asgi())
    ]

    6.启动django 项目如下图表示成功

    7.通过postman测试如下 表示websocket 配置成功

    项目目录

    项目依赖

    aioredis==1.3.1
    asgiref==3.4.1
    async-timeout==4.0.2
    attrs==21.4.0
    autobahn==22.1.1
    Automat==20.2.0
    certifi==2021.10.8
    cffi==1.15.0
    channels==3.0.4
    channels-redis==3.3.1
    charset-normalizer==2.0.9
    configparser==5.2.0
    constantly==15.1.0
    cryptography==36.0.1
    daphne==3.0.2
    Django==4.0
    django-cors-headers==3.10.1
    django-filter==21.1
    django-redis==5.1.0
    django-simpleui==2022.1
    djangorestframework==3.12.2
    djangorestframework-jwt==1.11.0
    hiredis==2.0.0
    hyperlink==21.0.0
    idna==3.3
    incremental==21.3.0
    msgpack==1.0.3
    pyasn1==0.4.8
    pyasn1-modules==0.2.8
    pycparser==2.21
    PyJWT==1.7.1
    PyMySQL==1.0.2
    pyOpenSSL==22.0.0
    pytz==2021.3
    redis==3.5.3
    requests==2.26.0
    service-identity==21.1.0
    six==1.16.0
    sqlparse==0.4.2
    Twisted==22.1.0
    txaio==21.2.1
    typing_extensions==4.0.1
    urllib3==1.26.7
    uWSGI==2.0.18
    zope.interface==5.4.0
  • 相关阅读:
    Jenkins Install
    提高C#代码质量的22条准则
    游戏程序员英文指南
    苹果设备内存指南
    Unity符号表
    UI优化策略-UI性能优化技巧
    C# 语言历史版本特性
    CPU SIMD介绍
    Unity渲染性能指标
    关于JMeter线程组中线程数,Ramp-Up Period,循环次数之间的设置概念
  • 原文地址:https://www.cnblogs.com/wangcongxing/p/15881910.html
Copyright © 2020-2023  润新知