mirror of
https://github.com/django/daphne.git
synced 2025-04-20 08:42:18 +03:00
Make group_send/demultiplex encode classmethods
This commit is contained in:
parent
cbe6afff85
commit
4370f043f7
|
@ -8,7 +8,8 @@ from ..generic.websockets import JsonWebsocketConsumer, WebsocketDemultiplexer
|
|||
|
||||
class WebsocketBinding(Binding):
|
||||
"""
|
||||
Websocket-specific outgoing binding subclass that uses JSON encoding.
|
||||
Websocket-specific outgoing binding subclass that uses JSON encoding
|
||||
and the built-in JSON/WebSocket multiplexer.
|
||||
|
||||
To implement outbound, implement:
|
||||
- group_names, which returns a list of group names to send to
|
||||
|
@ -26,7 +27,7 @@ class WebsocketBinding(Binding):
|
|||
|
||||
model = None
|
||||
|
||||
# Optional stream multiplexing
|
||||
# Stream multiplexing name
|
||||
|
||||
stream = None
|
||||
|
||||
|
@ -40,11 +41,7 @@ class WebsocketBinding(Binding):
|
|||
}
|
||||
# Encode for the stream
|
||||
assert self.stream is not None
|
||||
payload = WebsocketDemultiplexer.encode(self.stream, payload)
|
||||
# Return WS format message
|
||||
return {
|
||||
"text": json.dumps(payload),
|
||||
}
|
||||
return WebsocketDemultiplexer.encode(self.stream, payload)
|
||||
|
||||
def serialize_data(self, instance):
|
||||
"""
|
||||
|
|
|
@ -98,11 +98,12 @@ class WebsocketConsumer(BaseConsumer):
|
|||
else:
|
||||
raise ValueError("You must pass text or bytes")
|
||||
|
||||
def group_send(self, name, text=None, bytes=None):
|
||||
@classmethod
|
||||
def group_send(cls, name, text=None, bytes=None):
|
||||
if text is not None:
|
||||
Group(name, channel_layer=self.message.channel_layer).send({"text": text})
|
||||
Group(name).send({"text": text})
|
||||
elif bytes is not None:
|
||||
Group(name, channel_layer=self.message.channel_layer).send({"bytes": bytes})
|
||||
Group(name).send({"bytes": bytes})
|
||||
else:
|
||||
raise ValueError("You must pass text or bytes")
|
||||
|
||||
|
@ -153,8 +154,9 @@ class JsonWebsocketConsumer(WebsocketConsumer):
|
|||
"""
|
||||
super(JsonWebsocketConsumer, self).send(text=json.dumps(content))
|
||||
|
||||
def group_send(self, name, content):
|
||||
super(JsonWebsocketConsumer, self).group_send(name, json.dumps(content))
|
||||
@classmethod
|
||||
def group_send(cls, name, content):
|
||||
WebsocketConsumer.group_send(name, json.dumps(content))
|
||||
|
||||
|
||||
class WebsocketDemultiplexer(JsonWebsocketConsumer):
|
||||
|
@ -195,17 +197,18 @@ class WebsocketDemultiplexer(JsonWebsocketConsumer):
|
|||
raise ValueError("Invalid multiplexed frame received (no channel/payload key)")
|
||||
|
||||
def send(self, stream, payload):
|
||||
super(WebsocketDemultiplexer, self).send(self.encode(stream, payload))
|
||||
self.message.reply_channel.send(self.encode(stream, payload))
|
||||
|
||||
def group_send(self, name, stream, payload):
|
||||
super(WebsocketDemultiplexer, self).group_send(name, self.encode(stream, payload))
|
||||
@classmethod
|
||||
def group_send(cls, name, stream, payload):
|
||||
Group(name).send(cls.encode(stream, payload))
|
||||
|
||||
@classmethod
|
||||
def encode(cls, stream, payload):
|
||||
"""
|
||||
Encodes stream + payload for outbound sending.
|
||||
"""
|
||||
return {
|
||||
return {"text": json.dumps({
|
||||
"stream": stream,
|
||||
"payload": payload,
|
||||
}
|
||||
})}
|
||||
|
|
|
@ -175,6 +175,40 @@ that will do this for you if you call it explicitly.
|
|||
``self.close()`` is also provided to easily close the WebSocket from the server
|
||||
end once you are done with it.
|
||||
|
||||
.. _multiplexing:
|
||||
|
||||
WebSocket Multiplexing
|
||||
----------------------
|
||||
|
||||
Channels provides a standard way to multiplex different data streams over
|
||||
a single WebSocket, called a ``Demultiplexer``. You use it like this::
|
||||
|
||||
from channels.generic.websockets import WebsocketDemultiplexer
|
||||
|
||||
class Demultiplexer(WebsocketDemultiplexer):
|
||||
|
||||
mapping = {
|
||||
"intval": "binding.intval",
|
||||
"stats": "internal.stats",
|
||||
}
|
||||
|
||||
It expects JSON-formatted WebSocket frames with two keys, ``stream`` and
|
||||
``payload``, and will match the ``stream`` against the mapping to find a
|
||||
channel name. It will then forward the message onto that channel while
|
||||
preserving ``reply_channel``, so you can hook consumers up to them directly
|
||||
in the ``routing.py`` file, and use authentication decorators as you wish.
|
||||
|
||||
You cannot use class-based consumers this way as the messages are no
|
||||
longer in WebSocket format, though. If you need to do operations on
|
||||
``connect`` or ``disconnect``, override those methods on the ``Demultiplexer``
|
||||
itself (you can also provide a ``connection_groups`` method, as it's just
|
||||
based on the JSON WebSocket generic consumer).
|
||||
|
||||
The :doc:`data binding <binding>` code will also send out messages to clients
|
||||
in the same format, and you can encode things in this format yourself by
|
||||
using the ``WebsocketDemultiplexer.encode`` class method.
|
||||
|
||||
|
||||
Sessions and Users
|
||||
------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user