Django 中的 channels

Django Channels 

django channels 是django支持websocket的一个模块。

1. 安装

1
pip3 install channels

2. 快速上手 

2.1 在settings中添加配置

注册channels的app
ASGI_APPLICATION = "django_channels_demo.routing.application"
添加ASGI_APPLICATION支持websocket

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 业务逻辑
业务处理
原文地址:https://www.cnblogs.com/qidaii/p/11959622.html