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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM