Sample chat skeleton ¶
html
{% block extrajs %}
{{ block.super }}
<script language="javascript">
var log_counter = 0;
function log(message) {
var log = $('#log');
if (log_counter++ >= 100) {
log.val('');
log_counter = 0;
}
log.val(log.val() + message + '\n');
log.scrollTop(log[0].scrollHeight - log.height());
console.log(message);
}
$(function () {
// Correctly decide between ws:// and wss://
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
var ws_path = ws_scheme + '://' + window.location.host + "/gui/monitoring/";
console.log("Connecting to " + ws_path);
var socket = new ReconnectingWebSocket(ws_path);
var messageInput = $('#message-input');
messageInput.focus();
$('#log').on('dblclick', function() {
$(event.target).val('');
})
messageInput.on('keyup', function(event) {
if (event.keyCode === 13) {
var message = messageInput.val();
//log('send: "' + message + '"');
socket.send(JSON.stringify({
'message': message
}));
messageInput.val('');
messageInput.focus();
}
});
// Handle incoming messages
socket.onmessage = function (message) {
var data = JSON.parse(message.data);
if (data.type == 'monitoring_snapshot') {
$("#wallets_html").html(data.html);
}
}
// Helpful debugging
socket.onopen = function () {
log("Connected to monitoring socket");
};
socket.onclose = function () {
log("Disconnected from monitoring socket");
}
});
</script>
{% endblock extrajs %}
routing.py
from django.urls import path, re_path from channels.http import AsgiHandler from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from gui.consumers import MonitoringConsumer application = ProtocolTypeRouter({ "http": URLRouter([ # Our async news fetcher #path("collector/collect_news_async/", NewsCollectorAsyncConsumer), # AsgiHandler is "the rest of Django" - send things here to have Django # views handle them. re_path("^", AsgiHandler), ]), "websocket": AuthMiddlewareStack( URLRouter([ # URLRouter just takes standard Django path() or url() entries. path("gui/monitoring/", MonitoringConsumer), ]), ), })
consumers.py
# -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals import json from django.conf import settings from asgiref.sync import async_to_sync from channels.generic.websocket import JsonWebsocketConsumer MONITORING_GROUP_NAME = "gmonitoring" class MonitoringConsumer(JsonWebsocketConsumer): """ If you want to customise the JSON encoding and decoding, you can override the encode_json and decode_json classmethods. """ def connect(self): # Join monitoring group async_to_sync(self.channel_layer.group_add)( settings.CHANNELS_MONITORING_GROUP, self.channel_name ) # Accept connection super(MonitoringConsumer, self).connect() self.send( text_data=json.dumps({ 'type': 'connect', 'message': 'Connection accepted' }) ) # def receive(self, text_data=None, bytes_data=None): # """ # Sample input: # text_data = '{"message": "the quick brown fox"}' # bytes_data = None # """ # print('received: ' + text_data) # data = json.loads(text_data) # async_to_sync(self.channel_layer.group_send)( # settings.CHANNELS_MONITORING_GROUP, { # "type": "chat_message", # "message": data['message'].upper(), # }) def receive_json(self, content): """ Sample input: text_data = '{"message": "the quick brown fox"}' bytes_data = None """ print('received: ' + str(content)) async_to_sync(self.channel_layer.group_send)( settings.CHANNELS_MONITORING_GROUP, { "type": "chat_message", "message": content['message'].upper(), }) def disconnect(self, close_code): # Leave monitoring group async_to_sync(self.channel_layer.group_discard)( settings.CHANNELS_MONITORING_GROUP, self.channel_name ) def chat_message(self, event): # Send message to WebSocket print(str(event)) self.send_json(event) def monitoring_snapshot(self, event): # Send message to WebSocket print(str(event)) self.send_json(event)
daemon.py
import channels.layers from asgiref.sync import async_to_sync from channels.db import database_sync_to_async def broadcast_message(type, html): channel_layer = channels.layers.get_channel_layer() async_to_sync(channel_layer.group_send)( settings.CHANNELS_MONITORING_GROUP, { "type": "monitoring_snapshot", "html": html, })
