mirror of
https://github.com/django/daphne.git
synced 2025-10-18 09:34:15 +03:00
91 lines
3.0 KiB
Python
91 lines
3.0 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from django.utils import six
|
|
|
|
from channels import DEFAULT_CHANNEL_LAYER, channel_layers
|
|
|
|
|
|
class Channel(object):
|
|
"""
|
|
Public interaction class for the channel layer.
|
|
|
|
This is separate to the backends so we can:
|
|
a) Hide receive_many from end-users, as it is only for interface servers
|
|
b) Keep a stable-ish backend interface for third parties
|
|
|
|
You can pass an alternate Channel Layer alias in, but it will use the
|
|
"default" one by default.
|
|
"""
|
|
|
|
def __init__(self, name, alias=DEFAULT_CHANNEL_LAYER, channel_layer=None):
|
|
"""
|
|
Create an instance for the channel named "name"
|
|
"""
|
|
if isinstance(name, six.binary_type):
|
|
name = name.decode("ascii")
|
|
self.name = name
|
|
if channel_layer:
|
|
self.channel_layer = channel_layer
|
|
else:
|
|
self.channel_layer = channel_layers[alias]
|
|
|
|
def send(self, content, immediately=False):
|
|
"""
|
|
Send a message over the channel - messages are always dicts.
|
|
|
|
Sends are delayed until consumer completion. To override this, you
|
|
may pass immediately=True. If you are outside a consumer, things are
|
|
always sent immediately.
|
|
"""
|
|
from .message import pending_message_store
|
|
if not isinstance(content, dict):
|
|
raise TypeError("You can only send dicts as content on channels.")
|
|
if immediately or not pending_message_store.active:
|
|
self.channel_layer.send(self.name, content)
|
|
else:
|
|
pending_message_store.append(self, content)
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
|
|
class Group(object):
|
|
"""
|
|
A group of channels that can be messaged at once, and that expire out
|
|
of the group after an expiry time (keep re-adding to keep them in).
|
|
"""
|
|
|
|
def __init__(self, name, alias=DEFAULT_CHANNEL_LAYER, channel_layer=None):
|
|
if isinstance(name, six.binary_type):
|
|
name = name.decode("ascii")
|
|
self.name = name
|
|
if channel_layer:
|
|
self.channel_layer = channel_layer
|
|
else:
|
|
self.channel_layer = channel_layers[alias]
|
|
|
|
def add(self, channel):
|
|
if isinstance(channel, Channel):
|
|
channel = channel.name
|
|
self.channel_layer.group_add(self.name, channel)
|
|
|
|
def discard(self, channel):
|
|
if isinstance(channel, Channel):
|
|
channel = channel.name
|
|
self.channel_layer.group_discard(self.name, channel)
|
|
|
|
def send(self, content, immediately=False):
|
|
"""
|
|
Send a message to all channels in the group.
|
|
|
|
Sends are delayed until consumer completion. To override this, you
|
|
may pass immediately=True.
|
|
"""
|
|
from .message import pending_message_store
|
|
if not isinstance(content, dict):
|
|
raise ValueError("You can only send dicts as content on channels.")
|
|
if immediately or not pending_message_store.active:
|
|
self.channel_layer.send_group(self.name, content)
|
|
else:
|
|
pending_message_store.append(self, content)
|