Channels-django 실시간 전송 시스템
14724 단어 python&nodejs
django의 클래스 기반 보기와 유사하며,Channels도 클래스 기반 consumers를 제공합니다. 이런 consumers의 클래스는 같은 클래스BaseConsumer에서 계승됩니다.다음 코드를 사용하여 클래스를 가져올 수 있습니다.
from channels.generic import BaseConsumer
Channels는 각 메시지를 처리할 때 하나의 대상을 실례화하여 해당하는 메시지를 처리합니다.모든 종류의 실례에는 두 개의 속성이 있다.self.메시지 현재 처리 메시지,self.kwargs가 루트를 정의할 때 전달하는 매개 변수입니다.routings 사용 routeclass는route를 대체하여 클래스 기반consumers의 루트를 실현합니다.다음과 같습니다.
from channels import route, route_class
from . import consumers
channel_routing = [
route_class(consumers.ChatServer, path=r"^/chat/"),
]
모든 Consumer 클래스의 기본 클래스는 그대로 사용할 수 있습니다.
from channels.generic import BaseConsumer
class MyConsumer(BaseConsumer):
method_mapping = {
"channel.name.here": "method_name",
}
def method_name(self, message, **kwargs):
pass
method_mapping은 사전으로Channel 을 정의합니다.name에서 방법의 루트로 들어가면 루트에 들어간 정보는 해당하는 방법으로 처리됩니다.
WebsocketConsumer
채널은 웹소켓에 더 많이 사용되고, 채널은 웹소켓을 처리하기 위한 consumers 클래스를 제공합니다: WebsocketConsumer.다음과 같이 사용할 수 있습니다.
from channels.generic.websockets import WebsocketConsumer
class MyConsumer(WebsocketConsumer):
http_user = True # channels.auth django auth user channels
strict_ordering = False #
def connection_groups(self, **kwargs):
return ["test"] # , / /
def connect(self, message, **kwargs): #
self.message.reply_channel.send({"accept": True}) #True ( );False
def receive(self, text=None, bytes=None, **kwargs): #
self.send(text=text, bytes=bytes)
def disconnect(self, message, **kwargs): #
pass
위의 주석이 비교적 명확해서 여기는 더 이상 말하지 않겠다.그리고self.path는 현재 웹소켓 연결 주소의 경로를 표시합니다.
JsonWebsocketConsumer
웹소켓은 대부분 json 문자열을 전송하는데 편의를 위해 Json Websocket Consumer가 생겼다.이것은 위의 WebsocketConsumer와 상당히 유사하며, 다른 점은 receive 방법입니다.
def receive(self, content, **kwargs):#content json
self.send(content)
또한self를 제공했다.group_send(group name, content) 방법으로 메시지를 그룹화할 수 있으며 self를 통해 메시지를 만들 수 있습니다.close () 는 서버에서 웹소켓을 자발적으로 닫습니다.
웹소켓을 더욱 편리하게 사용하기 위해 채널스는 이 웹소켓 Demultiplexer 클래스를 제공합니다.이 종류의 작용은 웹소켓에서 json 메시지 전송 형식이 {"stream": "stream name", "payload": xxxx}stream은 다시 루트에 해당하고payload의 실제 데이터에 해당합니다.
from channels.generic.websockets import WebsocketDemultiplexer, JsonWebsocketConsumer
class EchoConsumer(websockets.JsonWebsocketConsumer):
def connect(self, message, multiplexer, **kwargs):
multiplexer.send({"status": "I just connected!"}) # multiplexer
def disconnect(self, message, multiplexer, **kwargs):
print("Stream %s is closed" % multiplexer.stream)
def receive(self, content, multiplexer, **kwargs):
multiplexer.send({"original_message": content}) # multiplexer
class AnotherConsumer(websockets.JsonWebsocketConsumer):
def receive(self, content, multiplexer=None, **kwargs):
pass
class Demultiplexer(WebsocketDemultiplexer):
consumers = { # stream
"echo": EchoConsumer,
"other": AnotherConsumer,
}
WebsocketDemultiplexer 같은 기능은 이뿐만이 아니다. 그는 귀속 모델을 실현할 수 있다. 모델이 바뀔 때 클라이언트에게 알리고 클라이언트도 모델을 바꾸는 명령을 보낼 수 있다. 이것은 mvm와 비슷한 프레임워크이다.이러한 기능은 나중에 다시 소개하겠습니다.
클래스 기반consumers에서session과user를 사용하려면 두 가지가 필요합니다.
class MyConsumer(WebsocketConsumer):
channel_session_user = True
http_user = True
channel_session_user가 True이면 메시지에 대한 메시지가 제공됩니다.channel_session 및 메시지.사용자 두 속성은 장식기로 이루어진 기능과 같습니다.http_사용자는 메시지만 복사했습니다.user.
class MyConsumer(WebsocketConsumer):
def get_handler(self, *args, **kwargs):
handler = super(MyConsumer, self).get_handler(*args, **kwargs)
return your_decorator(handler) #your_decorator
from . import consumers
channel_routing = [
consumers.ChatServer.as_route(path=r"^/chat/"),
]
위에서 타자 작업량을 줄이지 않은 것 같다. 이 예를 보자.
consumers.py:
class MyGenericConsumer(WebsocketConsumer):
group = 'default'
group_prefix = ''
def connection_groups(self, **kwargs):
return ['_'.join(self.group_prefix, self.group)]
routings.py:
from . import consumers
channel_routing = [
consumers.MyGenericConsumer.as_route(path=r"^/path/1/",
attrs={'group': 'one', 'group_prefix': 'pre'}),
consumers.MyGenericConsumer.as_route(path=r"^/path/2/",
attrs={'group': 'two', 'group_prefix': 'public'}),
]
여기는attrs 매개 변수를 통해 MyGenericConsumer 실례에 대응하는 클래스 속성을 다시 정의합니다.(이 예는 사실 path의 정규로 처리할 수 있다.)
2. 메시지 발송 지연
지연 발송의 의미는 현재 작업이 처리되지 않거나 지연 처리가 필요하며, 일정 시간을 기다린 후에 다시 시도해야 한다는 것이다. 그러면 지연 발송이 필요하다.Channels에서 채널을 제공합니다.delay의 응용으로 이런 장면을 처리한다.일단 이거 추가해서 인스타그램에 적용...APPS:
INSTALLED_APPS = [
...
'channels',
'channels.delay'
]
그런 다음 명령을 실행합니다.
python manage.py rundelay
이 명령이 실행되면 asgi를 감청합니다.delay의 channels.다음 코드를 통해 메시지를 지연시킬 수 있습니다.
from channels import Channel
delayed_message = {
'channel': 'example_channel',
'content': {'x': 1},
'delay': 10 * 1000
}
Channel('asgi.delay').send(delayed_message, immediately=True)
여기가 바로 10s 이후, {'x': 1}name에 example찬넬 찬넬 중입니다.이 기능은 사용자 정의 관리 명령에 맞추어 몇 시간마다 백엔드에서 정해진 시간을 수행하는 작업을 실현할 수 있다.
채널스를 사용하여 백그라운드 퀘스트를 진행하는 내용에 대해 기대해 주세요!