Python+Django+Channels之Consumers(用户)
Consumers
因为建立Channels最底层的解释接口是ASGI,被用来连接复杂应用的操作接口
当然你也可以忽略consumers而使用其他Channels部分,像routing,session等等
基础布局
consumers 的子类有
channels.consumer.AsyncConsumer
channels.consumer.SyncConsumerSyncConsumer的一个基础例子
from channels.consumer import SyncConsumer
class EchoConsumer(SyncConsumer):
def websocket_connect(self, event):
    self.send({
        "type": "websocket.accept",
    })
def websocket_receive(self, event):
    self.send({
        "type": "websocket.send",
        "text": event["text"],
    })</code></pre> 
通过在ASGI设置,我们可以获取到信息。
 
self.send(event)可以将事件发送到客户端或是服务器
 
与AsyncConsumer相似,其他的处理方法也要有self.send
 
from channels.consumer import AsyncConsumer
class EchoConsumer(AsyncConsumer):
async def websocket_connect(self, event):
    await self.send({
        "type": "websocket.accept",
    })
async def websocket_receive(self, event):
    await self.send({
        "type": "websocket.send",
        "text": event["text"],
    })</code></pre> 
什么时候使用AsyncConsumer或SyncConsumer?
 
当你使用慢同步函数循环整个事件时使用AsymcConsumer,如果你到用Django的ORM模型就应该使用SyncConsumer。一般使用SyncConsumer为默认值。
 
Closing Consumers关闭用户
 
当已连接的consumer要关闭时,需要使用http.disconnect或websocket.disconnect
 
当结束时会触发channels.exceptions.StopConsumer
 
Channel Layers
 
Consumer通过使用Channel Layers来相互发送消息或广播消息
 
Scope领域、范围
 
Consumuer能够接收连接所在的范围的消息
 
- scope["path"], the path on the request. (HTTP and WebSocket)
- scope["headers"], raw name/value header pairs from the request (HTTP and WebSocket)
- scope["method"], the method name used for the request. (HTTP)
WebSocketConsumer
 
这个包channels.generic.websocket.WebsocketConsumer是处理发送和接收消息。
 
from channels.generic.websocket import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
groups = ["broadcast"]
def connect(self):
    # Called on connection.
    # To accept the connection call:
    self.accept()
    # Or accept the connection and specify a chosen subprotocol.
    # A list of subprotocols specified by the connecting client
    # will be available in self.scope['subprotocols']
    self.accept("subprotocol")
    # To reject the connection, call:
    self.close()
def receive(self, text_data=None, bytes_data=None):
    # Called with either text_data or bytes_data for each frame
    # You can call:
    self.send(text_data="Hello world!")
    # Or, to send a binary frame:
    self.send(bytes_data="Hello world!")
    # Want to force-close the connection? Call:
    self.close()
    # Or add a custom WebSocket error code!
    self.close(code=4123)
def disconnect(self, close_code):
    # Called when the socket closes</code></pre> 
AsyncWebsocketConsumer
 
from channels.generic.websocket import AsyncWebsocketConsumer
class MyConsumer(AsyncWebsocketConsumer):
groups = ["broadcast"]
async def connect(self):
    # Called on connection.
    # To accept the connection call:
    await self.accept()
    # Or accept the connection and specify a chosen subprotocol.
    # A list of subprotocols specified by the connecting client
    # will be available in self.scope['subprotocols']
    await self.accept("subprotocol")
    # To reject the connection, call:
    await self.close()
async def receive(self, text_data=None, bytes_data=None):
    # Called with either text_data or bytes_data for each frame
    # You can call:
    await self.send(text_data="Hello world!")
    # Or, to send a binary frame:
    await self.send(bytes_data="Hello world!")
    # Want to force-close the connection? Call:
    await self.close()
    # Or add a custom WebSocket error code!
    await self.close(code=4123)
async def disconnect(self, close_code):
    # Called when the socket closes</code></pre> 
AsyncHttpConsumer
 
from channels.generic.http import AsyncHttpConsumer
class BasicHttpConsumer(AsyncHttpConsumer):
async def handle(self, body):
await asyncio.sleep(10)
await self.send_response(200, b"Your response bytes", headers=[
(b"Content-Type", b"text/plain"),
])
 
 
import json
from channels.generic.http import AsyncHttpConsumer
class LongPollConsumer(AsyncHttpConsumer):
async def handle(self, body):
await self.send_headers(headers=[
(b"Content-Type", b"application/json"),
])
# Headers are only sent after the first body event.
# Set "more_body" to tell the interface server to not
# finish the response yet:
await self.send_body(b"", more_body=True)
async def chat_message(self, event):
    # Send JSON and finish the response:
    await self.send_body(json.dumps(event).encode("utf-8"))</code></pre> 
 
 
from datetime import datetime
from channels.generic.http import AsyncHttpConsumer
class ServerSentEventsConsumer(AsyncHttpConsumer):
async def handle(self, body):
await self.send_headers(headers=[
(b"Cache-Control", b"no-cache"),
(b"Content-Type", b"text/event-stream"),
(b"Transfer-Encoding", b"chunked"),
])
while True:
payload = "data: %s\n\n" % datetime.now().isoformat()
await self.send_body(payload.encode("utf-8"), more_body=True)
await asyncio.sleep(1)
 
 
参考资料https://channels.readthedocs.io/en/stable/topics/consumers.html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号