mirror of
https://github.com/django/daphne.git
synced 2025-07-13 17:32:17 +03:00
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
import random
|
|
import string
|
|
|
|
from channels import DEFAULT_CHANNEL_BACKEND, channel_backends
|
|
|
|
|
|
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_BACKEND, channel_backend=None):
|
|
"""
|
|
Create an instance for the channel named "name"
|
|
"""
|
|
self.name = name
|
|
if channel_backend:
|
|
self.channel_backend = channel_backend
|
|
else:
|
|
self.channel_backend = channel_backends[alias]
|
|
|
|
def send(self, content):
|
|
"""
|
|
Send a message over the channel - messages are always dicts.
|
|
"""
|
|
if not isinstance(content, dict):
|
|
raise ValueError("You can only send dicts as content on channels.")
|
|
self.channel_backend.send(self.name, content)
|
|
|
|
@classmethod
|
|
def new_name(self, prefix):
|
|
"""
|
|
Returns a new channel name that's unique and not closed
|
|
with the given prefix. Does not need to be called before sending
|
|
on a channel name - just provides a way to avoid clashing for
|
|
response channels.
|
|
"""
|
|
return "%s.%s" % (prefix, "".join(random.choice(string.ascii_letters) for i in range(32)))
|
|
|
|
def as_view(self):
|
|
"""
|
|
Returns a view version of this channel - one that takes
|
|
the request passed in and dispatches it to our channel,
|
|
serialized.
|
|
"""
|
|
from channels.adapters import view_producer
|
|
return view_producer(self.name)
|
|
|
|
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_BACKEND, channel_backend=None):
|
|
self.name = name
|
|
if channel_backend:
|
|
self.channel_backend = channel_backend
|
|
else:
|
|
self.channel_backend = channel_backends[alias]
|
|
|
|
def add(self, channel):
|
|
if isinstance(channel, Channel):
|
|
channel = channel.name
|
|
self.channel_backend.group_add(self.name, channel)
|
|
|
|
def discard(self, channel):
|
|
if isinstance(channel, Channel):
|
|
channel = channel.name
|
|
self.channel_backend.group_discard(self.name, channel)
|
|
|
|
def channels(self):
|
|
return self.channel_backend.group_channels(self.name)
|
|
|
|
def send(self, content):
|
|
if not isinstance(content, dict):
|
|
raise ValueError("You can only send dicts as content on channels.")
|
|
self.channel_backend.send_group(self.name, content)
|