mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Websockets.. Work in progress!
websocket.html is just a blank page with the newest javascript helpers threading working wonderfully! Except my own code. websocket.html and thte bit from panel_handler.py can be deleted once this is done. It was just because the css and js kept loading for super long
This commit is contained in:
parent
31b311980c
commit
8cd2d59230
@ -8,6 +8,7 @@ import threading
|
||||
from app.classes.shared.helpers import helper
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.web.tornado import webserver
|
||||
from app.classes.web.websocket_handler import WebSocketHandler
|
||||
|
||||
from app.classes.minecraft.stats import stats
|
||||
from app.classes.shared.controller import controller
|
||||
@ -24,6 +25,7 @@ except ModuleNotFoundError as e:
|
||||
console.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class TasksManager:
|
||||
|
||||
def __init__(self):
|
||||
@ -38,6 +40,9 @@ class TasksManager:
|
||||
self.command_thread = threading.Thread(target=self.command_watcher, daemon=True, name="command_watcher")
|
||||
self.command_thread.start()
|
||||
|
||||
self.realtime_thread = threading.Thread(target=self.realtime_thread, daemon=True, name="realtime")
|
||||
self.realtime_thread.start()
|
||||
|
||||
def get_main_thread_run_status(self):
|
||||
return self.main_thread_exiting
|
||||
|
||||
@ -72,10 +77,8 @@ class TasksManager:
|
||||
|
||||
db_helper.mark_command_complete(c.get('command_id', None))
|
||||
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def _main_graceful_exit(self):
|
||||
try:
|
||||
os.remove(helper.session_file)
|
||||
@ -133,5 +136,33 @@ class TasksManager:
|
||||
logger.info("Scheduling Serverjars.com cache refresh service every 12 hours")
|
||||
schedule.every(12).hours.do(server_jar_obj.refresh_cache)
|
||||
|
||||
@staticmethod
|
||||
def realtime_thread():
|
||||
console.debug('realtime zero')
|
||||
while True:
|
||||
if len(WebSocketHandler.connections) > 0:
|
||||
print(WebSocketHandler)
|
||||
WebSocketHandler.broadcast(WebSocketHandler, 'sample_data', {
|
||||
'foo': 'bar',
|
||||
'baz': 'Hello, World!'
|
||||
})
|
||||
|
||||
if WebSocketHandler.host_stats.get('cpu_usage') != \
|
||||
db_helper.get_latest_hosts_stats().get('cpu_usage') or \
|
||||
WebSocketHandler.host_stats.get('mem_percent') != \
|
||||
db_helper.get_latest_hosts_stats().get('mem_percent'):
|
||||
|
||||
console.debug('realtime one')
|
||||
WebSocketHandler.host_stats = db_helper.get_latest_hosts_stats()
|
||||
if len(WebSocketHandler.connections) > 0:
|
||||
WebSocketHandler.broadcast(WebSocketHandler, 'update_host_stats', {
|
||||
'cpu': WebSocketHandler.host_stats.get('cpu_usage'),
|
||||
'mem': WebSocketHandler.host_stats.get('mem_percent')
|
||||
})
|
||||
time.sleep(4)
|
||||
else:
|
||||
console.debug('realtime two')
|
||||
time.sleep(2)
|
||||
|
||||
|
||||
tasks_manager = TasksManager()
|
||||
|
@ -65,6 +65,9 @@ class PanelHandler(BaseHandler):
|
||||
elif page == 'files_menu':
|
||||
template = "panel/files_menu.html"
|
||||
|
||||
elif page == 'websocket':
|
||||
template = "panel/websocket.html"
|
||||
|
||||
elif page == "remove_server":
|
||||
server_id = self.get_argument('id', None)
|
||||
server_data = controller.get_server_data(server_id)
|
||||
|
@ -24,6 +24,7 @@ try:
|
||||
from app.classes.web.server_handler import ServerHandler
|
||||
from app.classes.web.ajax_handler import AjaxHandler
|
||||
from app.classes.web.api_handler import ServersStats, NodeStats
|
||||
from app.classes.web.websocket_handler import WebSocketHandler
|
||||
|
||||
except ModuleNotFoundError as e:
|
||||
logger.critical("Import Error: Unable to load {} module".format(e, e.name))
|
||||
@ -125,6 +126,7 @@ class webserver:
|
||||
(r'/ajax/(.*)', AjaxHandler),
|
||||
(r'/api/stats/servers', ServersStats),
|
||||
(r'/api/stats/node', NodeStats),
|
||||
(r'/ws', WebSocketHandler),
|
||||
]
|
||||
|
||||
app = tornado.web.Application(
|
||||
|
37
app/classes/web/websocket_handler.py
Normal file
37
app/classes/web/websocket_handler.py
Normal file
@ -0,0 +1,37 @@
|
||||
import json
|
||||
|
||||
import tornado.websocket
|
||||
from app.classes.shared.console import console
|
||||
from app.classes.shared.models import db_helper
|
||||
|
||||
|
||||
class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||
connections = set()
|
||||
host_stats = db_helper.get_latest_hosts_stats()
|
||||
|
||||
def open(self):
|
||||
self.connections.add(self)
|
||||
console.debug('Opened WebSocket connection')
|
||||
self.broadcast('client_joined', {
|
||||
'foo': 'bar',
|
||||
})
|
||||
|
||||
def on_message(self, message):
|
||||
# broadcast
|
||||
# for client in self.connections:
|
||||
# client.write_message(message)
|
||||
|
||||
# send message to client this message was sent by
|
||||
# self.write_message
|
||||
|
||||
console.debug('Got message from WebSocket connection {}'.format(message))
|
||||
|
||||
def on_close(self):
|
||||
self.connections.remove(self)
|
||||
console.debug('Closed WebSocket connection')
|
||||
|
||||
def broadcast(self, message_type: str, data):
|
||||
print(str(json.dumps({'type': message_type, 'data': data})))
|
||||
message = str(json.dumps({'type': message_type, 'data': data}))
|
||||
for client in self.connections:
|
||||
client.write_message(message)
|
@ -58,6 +58,8 @@
|
||||
|
||||
<div class="main-panel">
|
||||
|
||||
<div class="warnings"></div>
|
||||
|
||||
{% block content %}
|
||||
{% end %}
|
||||
|
||||
@ -103,6 +105,82 @@
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
{% if request.protocol == 'https'%}
|
||||
let usingWebSockets = true;
|
||||
|
||||
let socketTypes = [];
|
||||
|
||||
try {
|
||||
|
||||
var wsInternal = new WebSocket('wss://' + location.host + '/ws');
|
||||
wsInternal.onopen = function() {
|
||||
console.log('opened WebSocket connection:', wsInternal)
|
||||
};
|
||||
wsInternal.onmessage = function (event) {
|
||||
var message = JSON.parse(event.data);
|
||||
|
||||
console.log('got message: ', message)
|
||||
|
||||
socketTypes
|
||||
.filter(event => event.type == message.type)
|
||||
.forEach(event => event.callback(message.data))
|
||||
}
|
||||
|
||||
|
||||
webSocket = {
|
||||
on: function (type, callback) {
|
||||
socketTypes.push({ type: type, callback: callback })
|
||||
},
|
||||
emit: function (type, data) {
|
||||
var message = {
|
||||
type: type,
|
||||
data: data
|
||||
}
|
||||
|
||||
wsInternal.send(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error while making websocket helpers', error);
|
||||
usingWebSockets = false;
|
||||
}
|
||||
{% else %}
|
||||
let usingWebSockets = false;
|
||||
warn('WebSockets are not supported in Crafty if not using the https protocol')
|
||||
{% end%}
|
||||
|
||||
function warn(message) {
|
||||
var closeEl = document.createElement('span');
|
||||
var strongEL = document.createElement('strong');
|
||||
var msgEl = document.createElement('div');
|
||||
|
||||
closeEl.innerHTML = '×';
|
||||
strongEL.textContent = 'Warning: ';
|
||||
msgEl.append(strongEL, message);
|
||||
|
||||
|
||||
closeEl.style.marginLeft = '15px';
|
||||
closeEl.style.fontWeight = 'bold';
|
||||
closeEl.style.float = 'right';
|
||||
closeEl.style.fontSize = '22px';
|
||||
closeEl.style.lineHeight = '20px';
|
||||
closeEl.style.cursor = 'pointer';
|
||||
closeEl.style.transition = '.3s';
|
||||
|
||||
closeEl.addEventListener('click', function () {this.parentElement.style.display='none';});
|
||||
|
||||
var parentEl = document.createElement('div');
|
||||
|
||||
parentEl.style.padding = '20px';
|
||||
parentEl.style.backgroundColor = '#f7970f';
|
||||
|
||||
parentEl.appendChild(closeEl);
|
||||
parentEl.appendChild(msgEl);
|
||||
|
||||
document.querySelector('.warnings').appendChild(parentEl);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
{% block js %}
|
||||
|
63
app/frontend/templates/panel/websocket.html
Normal file
63
app/frontend/templates/panel/websocket.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Default</title>
|
||||
</head>
|
||||
|
||||
<body class="dark-theme">
|
||||
<script>
|
||||
|
||||
{% if request.protocol == 'https'%}
|
||||
let usingWebSockets = true;
|
||||
|
||||
try {
|
||||
|
||||
function WebSocketManager (url) {
|
||||
|
||||
this.ws = new WebSocket(url);
|
||||
this.ws.eventListeners = [];
|
||||
this.ws.onopen = function() {
|
||||
console.log('opened WebSocket connection:', this.ws)
|
||||
};
|
||||
this.ws.onmessage = function (event) {
|
||||
var message = JSON.parse(event.data);
|
||||
|
||||
console.log('got message: ', message)
|
||||
|
||||
console.log(this)
|
||||
this.eventListeners
|
||||
.filter(event => event.type == message.type)
|
||||
.forEach(event => event.callback(message.data))
|
||||
}
|
||||
|
||||
this.on = function (type, callback) {
|
||||
this.ws.eventListeners.push({ type: type, callback: callback })
|
||||
}
|
||||
this.emit = function (type, data) {
|
||||
var message = {
|
||||
type: type,
|
||||
data: data
|
||||
}
|
||||
|
||||
this.ws.send(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
|
||||
webSocket = new WebSocketManager('wss://' + location.host + '/ws');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error while making websocket helpers', error);
|
||||
usingWebSockets = false;
|
||||
}
|
||||
{% else %}
|
||||
let usingWebSockets = false;
|
||||
console.warn('WebSockets are not supported in Crafty if not using the https protocol')
|
||||
{% end%}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user