Finish WebSockets

This commit is contained in:
luukas 2021-02-27 14:05:04 +02:00
parent 2595e6950d
commit 7691dc566e
4 changed files with 127 additions and 30 deletions

View File

@ -10,15 +10,16 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self): def open(self):
websocket_helper.addClient(self) websocket_helper.addClient(self)
console.debug('Opened WebSocket connection') console.debug('Opened WebSocket connection')
websocket_helper.broadcast('client_joined', {}) websocket_helper.broadcast('notification', 'New client connected')
def on_message(self, rawMessage): def on_message(self, rawMessage):
console.debug('Got message from WebSocket connection {}'.format(rawMessage)) console.debug('Got message from WebSocket connection {}'.format(rawMessage))
message = json.loads(rawMessage) message = json.loads(rawMessage)
console.debug('Type: {}, Data: {}'.format(message['type'], message['data'])) console.debug('Event Type: {}, Data: {}'.format(message['event'], message['data']))
def on_close(self): def on_close(self):
websocket_helper.removeClient(self) websocket_helper.removeClient(self)
console.debug('Closed WebSocket connection') console.debug('Closed WebSocket connection')
websocket_helper.broadcast('notification', 'Client disconnected')

View File

@ -13,7 +13,7 @@ class WebSocketHelper:
def broadcast(self, message_type: str, data): def broadcast(self, message_type: str, data):
console.debug('Sending: ' + str(json.dumps({'type': message_type, 'data': data}))) console.debug('Sending: ' + str(json.dumps({'type': message_type, 'data': data})))
message = str(json.dumps({'type': message_type, 'data': data})) message = str(json.dumps({'event': message_type, 'data': data}))
for client in self.clients: for client in self.clients:
try: try:
client.write_message(message) client.write_message(message)

View File

@ -77,6 +77,58 @@
</div> </div>
<style>
.notifications {
position: fixed;
width: 200px;
top: 70px;
right: 0px;
}
.notification {
position: relative;
box-sizing: border-box;
padding: 0.5rem;
padding-left: 0.7rem;
width: 180px;
margin-left: 10px;
margin-right: 10px;
background: #282a40;
transition: right 0.75s, opacity 0.75s, top 0.75s;
right: -6rem;
opacity: 0.1;
margin-bottom: 1rem;
z-index: 999;
top: 0px;
}
.notification.active {
right: 0rem;
opacity: 1;
}
.notification.remove {
right: 0rem;
opacity: 0.1;
top: -2rem;
}
.notification p {
margin: 0px;
width: calc(160.8px - 16px);
z-index: inherit;
}
.notification span {
position: absolute;
right: 0.5rem;
top: 0.46rem;
cursor: pointer;
font-weight: bold;
line-height: 20px;
font-size: 22px;
user-select: none;
z-index: inherit;
}
</style>
<div class="notifications"></div>
<script src="/static/assets/vendors/js/vendor.bundle.base.js"></script> <script src="/static/assets/vendors/js/vendor.bundle.base.js"></script>
<script src="/static/assets/js/shared/off-canvas.js"></script> <script src="/static/assets/js/shared/off-canvas.js"></script>
<script src="/static/assets/js/shared/hoverable-collapse.js"></script> <script src="/static/assets/js/shared/hoverable-collapse.js"></script>
@ -113,10 +165,10 @@
}); });
}); });
{% if request.protocol == 'https'%} {% if request.protocol == 'https' %}
let usingWebSockets = true; let usingWebSockets = true;
let socketTypes = []; let listenEvents = [];
try { try {
@ -124,24 +176,25 @@
wsInternal.onopen = function() { wsInternal.onopen = function() {
console.log('opened WebSocket connection:', wsInternal) console.log('opened WebSocket connection:', wsInternal)
}; };
wsInternal.onmessage = function (event) { wsInternal.onmessage = function (rawMessage) {
var message = JSON.parse(event.data); var message = JSON.parse(rawMessage.data);
console.log('got message: ', message) console.log('got message: ', message)
socketTypes listenEvents
.filter(event => event.type == message.type) .filter(listenedEvent => listenedEvent.event == message.event)
.forEach(event => event.callback(message.data)) .forEach(listenedEvent => listenedEvent.callback(message.data))
} }
webSocket = { webSocket = {
on: function (type, callback) { on: function (event, callback) {
socketTypes.push({ type: type, callback: callback }) console.log('registered ' + event + ' event');
listenEvents.push({ event: event, callback: callback })
}, },
emit: function (type, data) { emit: function (event, data) {
var message = { var message = {
type: type, event: event,
data: data data: data
} }
@ -155,6 +208,7 @@
{% else %} {% else %}
let usingWebSockets = false; let usingWebSockets = false;
warn('WebSockets are not supported in Crafty if not using the https protocol') warn('WebSockets are not supported in Crafty if not using the https protocol')
var webSocket;
{% end%} {% end%}
function warn(message) { function warn(message) {
@ -167,13 +221,12 @@
msgEl.append(strongEL, message); msgEl.append(strongEL, message);
closeEl.style.float = 'right';
closeEl.style.marginLeft = '15px'; closeEl.style.marginLeft = '15px';
closeEl.style.fontWeight = 'bold'; closeEl.style.fontWeight = 'bold';
closeEl.style.float = 'right';
closeEl.style.fontSize = '22px';
closeEl.style.lineHeight = '20px'; closeEl.style.lineHeight = '20px';
closeEl.style.fontSize = '22px';
closeEl.style.cursor = 'pointer'; closeEl.style.cursor = 'pointer';
closeEl.style.transition = '.3s';
closeEl.addEventListener('click', function () {this.parentElement.style.display='none';}); closeEl.addEventListener('click', function () {this.parentElement.style.display='none';});
@ -188,6 +241,49 @@
document.querySelector('.warnings').appendChild(parentEl); document.querySelector('.warnings').appendChild(parentEl);
} }
function closeNotification(element) {
element.parentElement.classList.add('remove');
setTimeout(function () {
element.parentElement.remove();
}, 500);
}
function notify(message) {
console.log(`notify(${message}})`);
var paragraphEl = document.createElement('p');
var closeEl = document.createElement('span');
paragraphEl.textContent = message;
closeEl.innerHTML = '&times;';
closeEl.addEventListener('click', function () {closeNotification(this)});
var parentEl = document.createElement('div');
parentEl.appendChild(paragraphEl);
parentEl.appendChild(closeEl);
parentEl.classList.add('notification');
document.querySelector('.notifications').appendChild(parentEl);
setTimeout(function () {
parentEl.classList.add('active');
}, 200);
setTimeout(function (element) {
closeNotification(element);
}, 7500, closeEl);
`
<div class="notification">
<p>Hello, World! This text should overflow</p>
<span>&times;</span>
</div>
`
}
webSocket.on('notification', notify);
</script> </script>
{% block js %} {% block js %}

View File

@ -266,20 +266,20 @@ $( document ).ready(function() {
message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; Please be patient while we restart the server<br /> This screen will refresh in a moment </div>' message: '<div align="center"><i class="fas fa-spin fa-spinner"></i> &nbsp; Please be patient while we restart the server<br /> This screen will refresh in a moment </div>'
}); });
}); });
if (webSocket) {
cpu_data = document.getElementById('cpu_data');
cpu_usage = document.getElementById('cpu_usage');
mem_usage = document.getElementById('mem_usage');
mem_percent = document.getElementById('mem_percent');
cpu_data = document.getElementById('cpu_data'); webSocket.on('update_host_stats', function (hostStats) {
cpu_usage = document.getElementById('cpu_usage'); var cpuDataTitle = `CPU Cores: ${hostStats.cpu_cores} <br /> CPU Cur Freq: ${hostStats.cpu_cur_freq} <br /> CPU Max Freq: ${hostStats.cpu_max_freq}`;
mem_usage = document.getElementById('mem_usage'); cpu_data.setAttribute('data-original-title', cpuDataTitle);
mem_percent = document.getElementById('mem_percent'); cpu_usage.textContent = hostStats.cpu_usage;
mem_usage.setAttribute('data-original-title', `Memory Usage: ${hostStats.mem_usage}`);
webSocket.on('update_host_stats', function (hostStats) { mem_percent.textContent = hostStats.mem_percent + '%';
var cpuDataTitle = `CPU Cores: ${hostStats.cpu_cores} <br /> CPU Cur Freq: ${hostStats.cpu_cur_freq} <br /> CPU Max Freq: ${hostStats.cpu_max_freq}`; });
cpu_data.setAttribute('data-original-title', cpuDataTitle); }
cpu_usage.textContent = hostStats.cpu_usage;
mem_usage.setAttribute('data-original-title', `Memory Usage: ${hostStats.mem_usage}`);
mem_percent.textContent = hostStats.mem_percent + '%';
});
}); });
</script> </script>