''' Author: your name Date: 2021-06-29 19:33:41 LastEditTime: 2021-07-01 04:03:21 LastEditors: Please set LastEditors Description: In User Settings Edit FilePath: \evm-store\backend\view\monitor.py ''' import tornado.ioloop import tornado.web from tornado.web import RequestHandler, StaticFileHandler from tornado.websocket import WebSocketHandler, WebSocketClosedError import json import signal import time import logging import pprint import traceback from datetime import datetime, timedelta from controller.monitor import insert_data, get_monitor_list, get_watch_list logger = logging.getLogger(__name__) def datetime2secs(mydate): return time.mktime(mydate.timetuple()) def secs2datetime(ts): return datetime.fromtimestamp(ts) class ObjectDict(dict): """Makes a dictionary behave like an object, with attribute-style access. """ def __getattr__(self, name): try: return self[name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): self[name] = value class GracefulExit(SystemExit): code = 1 def raise_graceful_exit(*args): tornado.ioloop.IOLoop.current().stop() print("Gracefully shutdown", args) raise GracefulExit() class BaseHandler(RequestHandler): """解决JS跨域请求问题""" def set_default_headers(self): self.set_header('Access-Control-Allow-Origin', '*') self.set_header('Access-Control-Allow-Methods', 'POST, GET') self.set_header('Access-Control-Max-Age', 1000) self.set_header('Access-Control-Allow-Headers', '*') self.set_header('Content-type', 'application/json') class WebsocketResponse(ObjectDict): def __init__(self, type="Response", api_code=-1, message='fail', data=None, traceback=""): super(WebsocketResponse, self).__init__() self.type = type self.code = api_code self.message = message self.data = data self.traceback = traceback if isinstance(self.data, list): self.count = len(self.data) def pushmessage(func): def send(*agrs, **kwargs): self = agrs[0] ret = func(*agrs, **kwargs) if ret: msg, binary = ret try: if isinstance(msg, WebsocketResponse) or isinstance(msg, dict): self.write_message(json.dumps(msg), binary) elif isinstance(msg, str) or isinstance(msg, str): self.write_message(msg, binary) else: self.write_message(repr(msg), binary) except WebSocketClosedError as e: logger.error(e) self.on_close() return send class BaseWebsocket(WebSocketHandler): handlers = {} def open(self): className = self.__class__.__name__ logger.warning("websocket of %s is opened" % className) if className not in self.handlers: self.handlers[className] = set() self.handlers[className].add(self) pprint.pprint(self.handlers) @pushmessage def send(self, message, binary=False): return message, binary def on_close(self): className = self.__class__.__name__ logger.warning("websocket of %s is closed" % className) if className in self.handlers: self.handlers[className].remove(self) def check_origin(self, origin): logger.info(origin) return True @classmethod def broadcastMessage(cls, message, binary=False): className = cls.__name__ pprint.pprint(cls.handlers) message = json.dumps(message) if className in cls.handlers: for handler in cls.handlers[className]: handler.send(message, binary) class NotifyHandler(BaseWebsocket): """ 建立与web前端的通信连接,发送状态信息报文 """ def open(self): super(NotifyHandler, self).open() def on_message(self, message): print("hello,world", message) logger.info(message) class MainHandler(BaseHandler): def get(self, *args, **kwargs): print("#############", args) print("/////////////", kwargs) print(self.request.path) # 请求路径 print(self.request.method) # 请求方法 print(self.request.host) # IP地址 print(self.request.protocol) # self.get_query_argument('a', value) # self.get_body_argument() # self.request.files self.write("Hello, world") def post(self): data = tornado.escape.json_decode(self.request.body) print("=====>", data, type(data)) self.write(json.dumps({ 'code': 100, 'msg': 'success' })) message = {'imei': '12345678900005', 'system': {'free_size': 0}, 'lvgl': {'total_size': 5242880, 'free_cnt': 31, 'free_size': 1279664, 'free_biggest_size': 1205448, 'used_cnt': 832, 'used_pct': 76, 'frag_pct': 6}, 'evm': {'total_size': 2097152, 'free_size': 0, 'gc_usage': 50}, 'image': [{'uri': 'evue_launcher', 'length': 1043, 'png_total_count': 0, 'png_uncompressed_size': 0, 'png_file_size': 0}, {'uri': 'kdgs_1_storyList', 'length': 9608, 'png_total_count': 193, 'png_uncompressed_size': 370884, 'png_file_size': 209807}]} insert_data(message) NotifyHandler.broadcastMessage(message) class WatchHandler(BaseHandler): def get(self, *args, **kwargs): # 获取手表列表 print("#############", args) print("/////////////", kwargs) print(self.request.path) # 请求路径 print(self.request.method) # 请求方法 print(self.request.host) # IP地址 print(self.request.protocol) try: result = get_watch_list() if result: self.write(json.dumps({ 'code': 200, 'data': result, 'msg': 'success' })) else: self.write(json.dumps({ 'code': 204, 'data': None, 'msg': 'no data' })) except Exception as e: logger.error(e) self.write(json.dumps({ 'code': 500, 'data': None, 'msg': 'server error' })) def post(self): data = tornado.escape.json_decode(self.request.body) print("=====>", data, type(data)) self.write(json.dumps({ 'code': 100, 'msg': 'success' })) class DeviceMessageHandler(BaseHandler): def get(self): if not self.get_argument('watch', None): self.write(json.dumps({ 'code': 400, 'msg': 'params error, watch can not be null' })) return try: watch = self.get_query_argument('watch') category = self.get_query_argument('category', 'all') start = self.get_query_argument('start', None) end = self.get_query_argument('end', None) if start and start.isdigit(): start = int(start) start = time.localtime(start) start = time.strftime("%Y-%m-%d %H:%M:%S", start) else: start = (datetime.now()-timedelta(minutes=10)).strftime("%Y-%m-%d %H:%M:%S") if end and end.isdigit(): end = time.localtime(int(end)) end = time.strftime("%Y-%m-%d %H:%M:%S", end) result = get_monitor_list(int(watch), category, start, end) if result: self.write(json.dumps({ 'code': 200, 'data': result, 'msg': 'success', 'type': 'array' if isinstance(result, list) else 'object' })) else: self.write(json.dumps({ 'code': 204, 'data': None, 'msg': 'no data' })) except Exception as e: logger.error(e) traceback.print_exc() self.write(json.dumps({ 'code': 500, 'data': None, 'msg': 'server error' })) def post(self): data = tornado.escape.json_decode(self.request.body) request = { 'host': self.request.remote_ip, 'path': self.request.path, 'protocol': self.request.protocol } data.update({ 'request': request }) insert_data(data) data['request'].update({ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") }) NotifyHandler.broadcastMessage(data) self.write(json.dumps({ 'code': 100, 'message': 'success' })) def make_app(): return tornado.web.Application([ (r"/", MainHandler), (r"/api/v1/evm_store/monitor", DeviceMessageHandler), (r"/api/v1/evm_store/watch", WatchHandler), (r"/ws/v1/notify", NotifyHandler), (r"/dist/(.*)", StaticFileHandler, { "path": "dist" }), ]) if __name__ == "__main__": app = make_app() app.listen(5001) signal.signal(signal.SIGINT, raise_graceful_exit) signal.signal(signal.SIGTERM, raise_graceful_exit) tornado.ioloop.IOLoop.current().start()