diff --git a/app/classes/shared/tasks.py b/app/classes/shared/tasks.py index 237d850c..e24e08ce 100644 --- a/app/classes/shared/tasks.py +++ b/app/classes/shared/tasks.py @@ -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() diff --git a/app/classes/web/panel_handler.py b/app/classes/web/panel_handler.py index 873ce834..75d2145b 100644 --- a/app/classes/web/panel_handler.py +++ b/app/classes/web/panel_handler.py @@ -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) diff --git a/app/classes/web/tornado.py b/app/classes/web/tornado.py index 03b0a97f..7867cad4 100644 --- a/app/classes/web/tornado.py +++ b/app/classes/web/tornado.py @@ -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( diff --git a/app/classes/web/websocket_handler.py b/app/classes/web/websocket_handler.py new file mode 100644 index 00000000..1c3ff38c --- /dev/null +++ b/app/classes/web/websocket_handler.py @@ -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) diff --git a/app/frontend/templates/base.html b/app/frontend/templates/base.html index 877de0c4..0499c104 100644 --- a/app/frontend/templates/base.html +++ b/app/frontend/templates/base.html @@ -58,6 +58,8 @@