Django Channels
django channels 是django支持websocket的一个模块。
1. 安装
1
|
pip3 install channels |
2. 快速上手
2.1 在settings中添加配置
注册channels的app
ASGI_APPLICATION = "django_channels_demo.routing.application"
2.2 创建websocket应用和路由
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from channels.routing import ProtocolTypeRouter, URLRouter 4 from django.conf.urls import url 5 from chat import consumers 6 7 8 application = ProtocolTypeRouter({ 9 'websocket': URLRouter([ 10 url(r'^chat/$', consumers.ChatConsumer), 11 ]) 12 })
2.3 编写处理websocket逻辑业务
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from channels.generic.websocket import WebsocketConsumer 4 from channels.exceptions import StopConsumer 5 6 class ChatConsumer(WebsocketConsumer): 7 8 def websocket_connect(self, message): 9 self.accept() 10 11 def websocket_receive(self, message): 12 print('接收到消息', message) 13 self.send(text_data='收到了') 14 15 def websocket_disconnect(self, message): 16 print('客户端断开连接了') 17 raise StopConsumer()
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from channels.generic.websocket import WebsocketConsumer 4 from channels.exceptions import StopConsumer 5 6 7 class SimpleChatConsumer(WebsocketConsumer): 8 def connect(self): 9 self.accept() 10 11 def receive(self, text_data=None, bytes_data=None): 12 self.send(text_data) 13 14 # 主动断开连接 15 # self.close() 16 17 def disconnect(self, code): 18 print('客户端要断开了') 19 20 示例二
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from channels.generic.websocket import WebsocketConsumer 4 from channels.exceptions import StopConsumer 5 6 7 CLIENTS = [] 8 9 class ChatConsumer(WebsocketConsumer): 10 11 def connect(self): 12 self.accept() 13 CLIENTS.append(self) 14 15 def receive(self, text_data=None, bytes_data=None): 16 for item in CLIENTS: 17 item.send(text_data) 18 19 # 主动断开连接 20 # self.close() 21 22 def disconnect(self, code): 23 CLIENTS.remove(self) 24 25 示例三
3. channel layer
基于内存的channel layer
1 CHANNEL_LAYERS = { 2 "default": { 3 "BACKEND": "channels.layers.InMemoryChannelLayer", 4 } 5 }
1 from channels.generic.websocket import WebsocketConsumer 2 from asgiref.sync import async_to_sync 3 4 5 class ChatConsumer(WebsocketConsumer): 6 7 def connect(self): 8 async_to_sync(self.channel_layer.group_add)('x1', self.channel_name) 9 self.accept() 10 11 def receive(self, text_data=None, bytes_data=None): 12 async_to_sync(self.channel_layer.group_send)('x1', { 13 'type': 'xxx.ooo', 14 'message': text_data 15 }) 16 17 def xxx_ooo(self, event): 18 message = event['message'] 19 self.send(message) 20 21 def disconnect(self, code): 22 async_to_sync(self.channel_layer.group_discard)('x1', self.channel_name) 23 24 业务处理
基于 redis的channel layer
pip3 install channels
-
redis
1 CHANNEL_LAYERS = { 2 "default": { 3 "BACKEND": "channels_redis.core.RedisChannelLayer", 4 "CONFIG": { 5 "hosts": [('10.211.55.25', 6379)] 6 }, 7 }, 8 } 9 10 11 CHANNEL_LAYERS = { 12 'default': { 13 'BACKEND': 'channels_redis.core.RedisChannelLayer', 14 'CONFIG': {"hosts": ["redis://10.211.55.25:6379/1"],}, 15 }, 16 } 17 18 19 CHANNEL_LAYERS = { 20 'default': { 21 'BACKEND': 'channels_redis.core.RedisChannelLayer', 22 'CONFIG': {"hosts": [('10.211.55.25', 6379)],},}, 23 } 24 25 26 CHANNEL_LAYERS = { 27 "default": { 28 "BACKEND": "channels_redis.core.RedisChannelLayer", 29 "CONFIG": { 30 "hosts": ["redis://:password@10.211.55.25:6379/0"], 31 "symmetric_encryption_keys": [SECRET_KEY], 32 }, 33 }, 34 } 35 36 配置
1 from channels.generic.websocket import WebsocketConsumer 2 from asgiref.sync import async_to_sync 3 4 5 class ChatConsumer(WebsocketConsumer): 6 7 def connect(self): 8 async_to_sync(self.channel_layer.group_add)('x1', self.channel_name) 9 self.accept() 10 11 def receive(self, text_data=None, bytes_data=None): 12 async_to_sync(self.channel_layer.group_send)('x1', { 13 'type': 'xxx.ooo', 14 'message': text_data 15 }) 16 17 def xxx_ooo(self, event): 18 message = event['message'] 19 self.send(message) 20 21 def disconnect(self, code): 22 async_to_sync(self.channel_layer.group_discard)('x1', self.channel_name) 23 24 业务逻辑