Loading
@codeadict
www.dairon.org
Developer with Python and other daemons at
Based on a request/response model, was not evolving with the modern web.
Traditional Django Architecture
Mozilla Foundation helped with $150,000 in funds on December 2015.
Announced as an official Django project on September 2016, will be merged into the Django core, hopefully soon.
https://www.djangoproject.com/weblog/2016/sep/09/channels-adopted-official-django-project/
https://github.com/django/channels
Channels adds a new layer to Django, allowing some important improvements for real time web and message passing. Can be used for:
$ pip install channels
$ ./manage.py runserver
$ ./manage.py runworker
# Define channel layers
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'asgi_redis.RedisChannelLayer',
'CONFIG': {
'hosts': [os.environ.get('REDIS_URL', 'redis://localhost:6379')],
},
'ROUTING': 'core.urls.channel_routing',
},
}
from channels import route
from .consumers import (
ws_connect, ws_receive, ws_disconnect
)
websocket_routing = [
route('websocket.connect', ws_connect),
route('websocket.receive', ws_receive),
route('websocket.disconnect', ws_disconnect),
]
route("websocket.connect", connect_light, path=r'^/lights/(?P<slug>[^/]+)/stream/$')
class LightsConsumer(WebsocketConsumer):
# Set to True to automatically port users from HTTP cookies
http_user = True
# Set to True if you want it, else leave it out
strict_ordering = False
def connection_groups(self, **kwargs):
"""
Add this connection to the Group lights.
"""
return ["lights.receive"]
def connect(self, message, **kwargs):
"""
Do things on connection start
"""
# Accept the connection
self.message.reply_channel.send({"accept": True})
def receive(self, text=None, **kwargs):
"""
Called when a message is received with either text or bytes
filled out.
"""
payload = json.loads(text)
self.send(text=payload)
def disconnect(self, message, **kwargs):
"""
Perform things on connection close
"""
pass
import json
from channels import Channel, Group
def ws_connect(message):
message.reply_channel.send({'accept': True})
Group('lights').add(message.reply_channel)
def ws_receive(message):
payload = json.loads(message['text'])
payload['reply_channel'] = message.content['reply_channel']
Channel('lights.receive').send(payload)
def ws_disconnect(message):
Group('lights').discard(message.reply_channel)
def send_status_update(self):
"""
Sends a status updates to subscribed channels.
"""
command = {
"light_id": self.id,
"status": self.status,
"created": self.created.strftime("%a %d %b %Y %H:%M"),
}
Group('lights').send({
# WebSocket text frame, with JSON content
"text": json.dumps(command),
})
def save(self, *args, **kwargs):
"""
Hooking send_notification into the save of the object.
"""
result = super().save(*args, **kwargs)
self.send_status_update()
return result
$(function () {
var ws_scheme = window.location.protocol == 'https:' ? 'wss' : 'ws';
var ws_path = ws_scheme + '://' + window.location.host + '/lights/stream/';
var socket = new ReconnectingWebSocket(ws_path);
// Handle incoming messages
socket.onmessage = function (message) {
// Decode the JSON
var data = JSON.parse(message.data);
if (data.error) {
alert(data.error);
return;
}
if (data.light_id == {{ object.id }}) {
if (data.status === 1) {
$('body').removeClass('lightbulb--is-on').addClass('lightbulb--is-on');
} else {
$('body').removeClass('lightbulb--is-on');
}
}
};
});
https://github.com/codeadict/ChannelsLightsControl
Muchas Gracias!