依赖
- 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()