mirror of
https://github.com/django/daphne.git
synced 2025-07-13 09:22:17 +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):
|
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:
|
To implement outbound, implement:
|
||||||
- group_names, which returns a list of group names to send to
|
- group_names, which returns a list of group names to send to
|
||||||
|
@ -26,7 +27,7 @@ class WebsocketBinding(Binding):
|
||||||
|
|
||||||
model = None
|
model = None
|
||||||
|
|
||||||
# Optional stream multiplexing
|
# Stream multiplexing name
|
||||||
|
|
||||||
stream = None
|
stream = None
|
||||||
|
|
||||||
|
@ -40,11 +41,7 @@ class WebsocketBinding(Binding):
|
||||||
}
|
}
|
||||||
# Encode for the stream
|
# Encode for the stream
|
||||||
assert self.stream is not None
|
assert self.stream is not None
|
||||||
payload = WebsocketDemultiplexer.encode(self.stream, payload)
|
return WebsocketDemultiplexer.encode(self.stream, payload)
|
||||||
# Return WS format message
|
|
||||||
return {
|
|
||||||
"text": json.dumps(payload),
|
|
||||||
}
|
|
||||||
|
|
||||||
def serialize_data(self, instance):
|
def serialize_data(self, instance):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -98,11 +98,12 @@ class WebsocketConsumer(BaseConsumer):
|
||||||
else:
|
else:
|
||||||
raise ValueError("You must pass text or bytes")
|
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:
|
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:
|
elif bytes is not None:
|
||||||
Group(name, channel_layer=self.message.channel_layer).send({"bytes": bytes})
|
Group(name).send({"bytes": bytes})
|
||||||
else:
|
else:
|
||||||
raise ValueError("You must pass text or bytes")
|
raise ValueError("You must pass text or bytes")
|
||||||
|
|
||||||
|
@ -153,8 +154,9 @@ class JsonWebsocketConsumer(WebsocketConsumer):
|
||||||
"""
|
"""
|
||||||
super(JsonWebsocketConsumer, self).send(text=json.dumps(content))
|
super(JsonWebsocketConsumer, self).send(text=json.dumps(content))
|
||||||
|
|
||||||
def group_send(self, name, content):
|
@classmethod
|
||||||
super(JsonWebsocketConsumer, self).group_send(name, json.dumps(content))
|
def group_send(cls, name, content):
|
||||||
|
WebsocketConsumer.group_send(name, json.dumps(content))
|
||||||
|
|
||||||
|
|
||||||
class WebsocketDemultiplexer(JsonWebsocketConsumer):
|
class WebsocketDemultiplexer(JsonWebsocketConsumer):
|
||||||
|
@ -195,17 +197,18 @@ class WebsocketDemultiplexer(JsonWebsocketConsumer):
|
||||||
raise ValueError("Invalid multiplexed frame received (no channel/payload key)")
|
raise ValueError("Invalid multiplexed frame received (no channel/payload key)")
|
||||||
|
|
||||||
def send(self, stream, payload):
|
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):
|
@classmethod
|
||||||
super(WebsocketDemultiplexer, self).group_send(name, self.encode(stream, payload))
|
def group_send(cls, name, stream, payload):
|
||||||
|
Group(name).send(cls.encode(stream, payload))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def encode(cls, stream, payload):
|
def encode(cls, stream, payload):
|
||||||
"""
|
"""
|
||||||
Encodes stream + payload for outbound sending.
|
Encodes stream + payload for outbound sending.
|
||||||
"""
|
"""
|
||||||
return {
|
return {"text": json.dumps({
|
||||||
"stream": stream,
|
"stream": stream,
|
||||||
"payload": payload,
|
"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
|
``self.close()`` is also provided to easily close the WebSocket from the server
|
||||||
end once you are done with it.
|
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
|
Sessions and Users
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user