首页 |  我的博客 |  查看该博主内容分类 | 

给django配置websocket(channels)

依赖

  • python库
    pip install django==4.0.5 channels==3.0.5 channels-redis websockets

    pip install django==3.2.19 channels==4.0.0 channels-redis==4.1.0 websockets(推荐)
    以上websockets包均可换成uvicorn,看你的环境支持哪个就安装哪个。
  • reids
    Linux:yum install redis
    Win:https://github.com/MicrosoftArchive/redis/releases 下载安装最新msi结尾的

settings.py

INSTALLED_APPS = [
	...,
	'channels'
]
ASGI_APPLICATION = '项目名.asgi.application'

CHANNEL_LAYERS = {
    'default':  {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            # 'hosts': ['redis://:password@127.0.0.1:6379/1'],
            # 'symmetric_encryption_keys': ['redis123'],
            'hosts': [('127.0.0.1', 6379)],
        }
    }
}

routing.py(同settings.py下新建)

from django.urls import path

from api import consumers

websocket_urlpatterns = [
    path(r'room/<str:group>', consumers.ChatConsumer.as_asgi()),
]

asgi.py(同settings.py路径)

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application

from DjangoBase import routings

# application = get_asgi_application()

application = ProtocolTypeRouter({
    'http': get_asgi_application(),
    'websocket': URLRouter(routings.websocket_urlpatterns)
})

consumers.py(应用下,如api)

import json

from asgiref.sync import async_to_sync
from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumer

from api.ext import return_code


class ChatConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        print(message, '已连接')
        # 客户端连接时的回调函数
        self.accept()  # 允许连接
        # self.send('服务端:你的连接请求已通过!')   # 向客户端发送消息
        group = self.scope['url_route']['kwargs'].get('group')  # self.scope['url_route']['kwargs']路由的参数
        async_to_sync(self.channel_layer.group_add)(group, self.channel_name)

    def websocket_receive(self, message):
        # 收到消息时的回调函数
        print(message)
        # self.send(f'《{message["text"]}》已收到!')   # 向个人发送消息
        group = self.scope['url_route']['kwargs'].get('group')
        async_to_sync(self.channel_layer.group_send)(group, {
            'type': 'xx',  # xx本类中自定义方法
            'message': message
        })  # 向群发送消息
        # self.close()  # 服务端端口连接
        # raise StopConsumer()   #  如果使用self.close后,不想执行websocket_disconnect方法,使用raise StopConsumer()

    def xx(self, event):
        text = event['message']['text']
        self.send(json.dumps({'code': return_code.SUCCESS, 'data': text}))

    def websocket_disconnect(self, message):
        print(message, '断开连接')
        group = self.scope['url_route']['kwargs'].get('group')
        async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)
        raise StopConsumer()
posted @ 2023-08-30 11:28  Z哎呀  阅读(164)  评论(0)    收藏  举报