1.1 安装
pip3 install channels
pip3 install channels-redis
pip3 install asgiref
1.2 后端核心代码
-
配置
settings.py
INSTALLED_APPS = [ ..., 'channels', ] # channels配置 ASGI_APPLICATION = '项目名.asgi.application' CHANNEL_LAYERS = { 'default': { 'BACKEND': 'channels_redis.core.RedisChannelLayer', 'CONFIG': { "hosts": [('0.0.0.0', 6379)], }, }, }
-
asgi.py
import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'helloxjn.settings') django.setup() # 置顶,防止运行daphne时报错 from channels.security.websocket import AllowedHostsOriginValidator from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter from django.core.asgi import get_asgi_application import app_site.routing application = ProtocolTypeRouter({ "http": get_asgi_application(), # channels websocket配置 "websocket": AllowedHostsOriginValidator( AuthMiddlewareStack( URLRouter( # 解耦:路由分发 app_site.routing.websocket_urlpatterns ) ), ), })
-
路由
app_site/routing.py
from django.urls import re_path from . import consumers websocket_urlpatterns = [ # 路由分发 re_path(r'home/(?P<room_name>\w+)/$', consumers.ChatConsumer.as_asgi()), ]
-
消费者
app_site/consumers.py
import json from channels.generic.websocket import AsyncWebsocketConsumer from utils.db_redis import r class ChatConsumer(AsyncWebsocketConsumer): async def connect(self): """ 连接websocket """ self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name await self.channel_layer.group_add( self.room_group_name, self.channel_name ) await self.accept() async def disconnect(self, close_code): """ 断开连接 """ await self.channel_layer.group_discard( self.room_group_name, self.channel_name ) async def receive(self, text_data): """ 从websocket收到消息 """ # 定制自己的业务逻辑 like_num = r.incrby('like_num', 1) # 将更新后的数据发布到websocket await self.channel_layer.group_send( self.room_group_name, { 'type': 'chat_message', 'message': like_num } ) async def chat_message(self, event): """ 发布数据到websocket """ await self.send(text_data=json.dumps({ 'message': event['message'] }))
1.3 前端核心代码
-
javascript
代码// 使用channels完成实时更新点赞 let is_close = false; const chatSocket = new WebSocket(`ws://${window.location.host}/home/like_num/`); // http连接 // const chatSocket = new WebSocket(`wss://${window.location.host}/home/like_num/`); // https连接 // 收到websocket实时发布的数据 chatSocket.onmessage = function (e) { $('.like-num').html(JSON.parse(e.data).message); }; // 关闭连接 chatSocket.onclose = function (e) { console.error('websocket 连接断开'); is_close = true; }; // 点赞 function send_like() { // 发送数据到websocket chatSocket.send(JSON.stringify({ 'message': '点赞了' })); ... }