Esempio n. 1
0
 async def handler(self, websocket, path):
     remoteIP, remotePort = websocket.remote_address
     remoteHost = str(remoteIP) + ':' + str(remotePort)
     peer = Peer(websocket, remoteHost, self.__callbackWrapper,
                 self.connectionHandler, self.settings, self.TAG)
     try:
         while peer.run:
             message = await asyncio.wait_for(
                 websocket.recv(), timeout=self.settings.TIMEOUT_SECONDS)
             if peer.run:
                 asyncio.Task(peer.send_response(message))
             else:
                 break
     except asyncio.TimeoutError:
         logger.log_error(('TImeout: client {0}, peer {1}'.format(
             peer.client_id, peer.id)), self.TAG)
     finally:
         if peer.client_id != None:
             if peer.run:
                 await self.connectionHandler.disconnect_client(
                     peer.client_id)
             logger.log_info(('Conn closed: client {0}, peer {1}'.format(
                 peer.client_id, peer.id)), self.TAG)
         else:
             logger.log_info(('Conn closed: peer {0}'.format(peer.id)),
                             self.TAG)
         try:
             websocket.close()
         except:
             pass
         return
Esempio n. 2
0
 def __parse_settings(self):
     # self.__settings = ServerSettings()
     settings = {}
     default = False
     if self.__configFile is None or len(self.__configFile) == 0:
         self.__configFile = os.path.join(root_path, 'core', 'default.conf')
         default = True
     with open(self.__configFile) as fin:
         for line in fin:
             if not str(line).startswith('#'):
                 configStrs = line.split('=', 1)
                 if len(configStrs) == 2:
                     key = configStrs[0].strip()
                     value = str(configStrs[1]).strip('\n').strip()
                     try:
                         value = int(value)
                     except:
                         value = str(value).replace('"','').replace("'","")
                     settings[key] = value
     
     self.__settings = ServerSettings(settings)
     # create the JMQT logger (get_logger function returns this logger)
     logger.set_logger(self.__settings.LOG_PATH, mode = self.__settings.LOG_MODE)
     if default:
         logger.log_info('No config file passed, falling back to default config "' + self.__configFile + '"')
     else:
         logger.log_info('Loading config "' + self.__configFile + '"')
Esempio n. 3
0
 def start(self):
     logger.log_info(
         ('Listening on tcp {0}'.format(self.settings.WEBSOCKET_PORT)),
         self.TAG)
     self.server = self.loop.run_until_complete(
         websockets.serve(self.handler, '0.0.0.0',
                          self.settings.WEBSOCKET_PORT))
Esempio n. 4
0
 async def disconnect(self):
     self.run = False
     self.writer.close()
     if self.client_id != None:
         logger.log_info(('Conn closed: client {0}, peer {1}'.format(
             self.client_id, self.id)), self.tag)
     else:
         logger.log_info(('Conn closed: peer {0}'.format(self.id)),
                         self.tag)
Esempio n. 5
0
 def start(self):
     logger.log_info(
         ('Listening on tcp {0}'.format(self.settings.SOCKET_PORT)),
         self.TAG)
     self.coro = asyncio.start_server(self.handle_client,
                                      '',
                                      self.settings.SOCKET_PORT,
                                      loop=self.loop)
     self.server = self.loop.run_until_complete(self.coro)
Esempio n. 6
0
 def connect_sqlite(self):
     root_path = os.path.dirname(os.path.realpath(__file__))
     db_path = os.path.join(root_path, 'jmqt.db')
     logger.log_info('Connecting SQLite Db ' + db_path, 'SQLiteService')
     db = SqliteDatabase(db_path)
     DB_PROXY.initialize(db)
     db.connect()
     db.create_tables(
         [Connections, Subscriptions, RetainedPackets, Packets, Pubmaps],
         safe=True)
Esempio n. 7
0
 def start(self):
     logger.log_info(
         ('Listening on tcp {0}'.format(self.settings.SSL_WEBSOCKET_PORT)),
         self.TAG)
     sc = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
     sc.load_cert_chain(self.settings.SSL_CERT_PATH,
                        self.settings.SSL_KEY_PATH)
     self.server = self.loop.run_until_complete(
         websockets.serve(self.handler,
                          '0.0.0.0',
                          self.settings.SSL_WEBSOCKET_PORT,
                          ssl=sc))
Esempio n. 8
0
 def start(self):
     logger.log_info(
         ('Listening on tcp {0}'.format(self.settings.SSL_SOCKET_PORT)),
         self.TAG)
     sc = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
     sc.load_cert_chain(self.settings.SSL_CERT_PATH,
                        self.settings.SSL_KEY_PATH)
     self.coro = asyncio.start_server(self.handle_client,
                                      '',
                                      self.settings.SSL_SOCKET_PORT,
                                      ssl=sc,
                                      loop=self.loop)
     self.server = self.loop.run_until_complete(self.coro)
Esempio n. 9
0
 def connect_mysql(self):
     logger.log_info(('Connecting MySQL/MariaDb {0} on {1}:{2}').format(
         self.settings.MYSQL_DB, self.settings.MYSQL_HOST,
         self.settings.MYSQL_PORT), 'MySQLService')
     db = MySQLDatabase(self.settings.MYSQL_DB,
                        user=self.settings.MYSQL_USER,
                        password=self.settings.MYSQL_PSWD,
                        host=self.settings.MYSQL_HOST,
                        port=self.settings.MYSQL_PORT)
     DB_PROXY.initialize(db)
     db.connect()
     db.create_tables(
         [Connections, Subscriptions, RetainedPackets, Packets, Pubmaps])
Esempio n. 10
0
 def __init__(self, settings, eventLoop):
     self.server_id = str(uuid.uuid4())
     self.settings = settings
     self.loop = eventLoop
     self.peers = {}
     self.pubmap = {}
     if not self.settings.ENABLE_MYSQL and self.settings.ENABLE_REDIS:
         logger.log_warning("MySQL/MariaDb is disbled, but Redis is enabled. Distributed system won't work without MySQL/MariaDb", 'ConnectionHandler')
     if self.settings.ENABLE_MYSQL:
         logger.log_info('MySQL/MariaDb is enabled. Initiating MySQL/MariaDb..', 'ConnectionHandler')
         from pyjmqt.server.core.services.dbservice import MySQLService
         self.dbService = MySQLService(self.settings)
     else:
         logger.log_info('MySQL/MariaDb is disabled. Switching to SQLite..', 'ConnectionHandler')
         from pyjmqt.server.core.services.dbservice import SQLiteService
         self.dbService = SQLiteService(self.settings)
     self.cacheService = CacheService(self.settings, self.loop, self.server_id, self.dbService, self.__process_pub, self.disconnect_client)
Esempio n. 11
0
 async def create_response(self, packet, peer):
     response = None
     data = {}
     if (packet != None):
         #auth handler
         if packet.packetType == PacketTypes.auth:
             auth_data = PacketParser.get_arg(JSONKeys.data, packet.packetData)
             status_code, client_id, auth_token, message = await peer.callbackWrapper.validate_auth_callback(auth_data, peer.address, packet.protocol)
             if status_code != StatusCode.OK:
                 log_msg = ('Auth FAILED: auth Data {1}, message {0} [{2}]').format(message, auth_data, peer.id)
                 logger.log_warning(log_msg, peer.tag)
             response = PacketGenerator.generate_auth_res(status_code, client_id, auth_token, message)
         #conn handler
         elif packet.packetType == PacketTypes.conn:
             auth_token = PacketParser.get_arg(JSONKeys.authToken, packet.packetData)
             client_id = PacketParser.get_arg(JSONKeys.clientId, packet.packetData)
             status_code = await peer.callbackWrapper.validate_conn_callback(client_id, auth_token, peer.address, packet.protocol)
             if status_code == StatusCode.OK:
                 connected = await self.connect_client(auth_token, client_id, packet.protocol, peer)
                 if connected:
                     status_code = StatusCode.OK
                     data = {'client_id' : client_id}
                     info_msg = ('Connnected: client {0} {1}').format(client_id, peer.id)
                     logger.log_info(info_msg, peer.tag)
                 else:
                     status_code = StatusCode.NOT_ALLOWED
             if status_code != StatusCode.OK:
                 log_msg = ('Conn FAILED: token {1}, status {0} {2}').format(status_code, auth_token, peer.id)
                 logger.log_warning(log_msg, peer.tag)
             response = PacketGenerator.generate_conn_res(status_code, self.settings.TIMEOUT_SECONDS)
         elif peer.client_id != None:
             #disconn handler
             if packet.packetType == PacketTypes.disconn:
                 pck_id = PacketParser.get_arg(JSONKeys.packetId, packet.packetData)
                 await self.disconnect_client(peer.client_id, has_client_disconnected = True)
                 log_msg = ('disconn from client {0} {1}').format(peer.client_id, peer.id)
                 logger.log_info(log_msg, peer.tag)
             #pub handler
             elif packet.packetType == PacketTypes.pub:
                 channel_name = PacketParser.get_arg(JSONKeys.channelName, packet.packetData)
                 channel_valid, channel_name = self.is_channel_valid(channel_name)
                 pck_id = PacketParser.get_arg(JSONKeys.packetId, packet.packetData)
                 if channel_valid:
                     data = PacketParser.get_arg(JSONKeys.data, packet.packetData)
                     retain_flag = PacketParser.get_arg(JSONKeys.retainFlag, packet.packetData, False)
                     qos = PacketParser.get_arg(JSONKeys.qos, packet.packetData, QOS.ZERO)
                     if not self.is_channel_control(channel_name):
                         status_code = await peer.callbackWrapper.validate_pub_callback(peer.client_id, channel_name, data, qos, peer.address, packet.protocol)
                         if status_code != StatusCode.OK:
                             log_msg = ('Pub FAILED channel {0} from client {1} , qos {3}, retain {4} {2} : status {5}').format(channel_name, peer.client_id, peer.id, qos, retain_flag, status_code)
                             logger.log_warning(log_msg, peer.tag)
                         else:
                             log_msg = ('Pub OK channel {0} from client {1} , qos {3}, retain {4} {2}').format(channel_name, peer.client_id, peer.id, qos, retain_flag)
                             logger.log_debug(log_msg, peer.tag)
                         if status_code == StatusCode.OK:
                             status_code = await self.pub(peer.client_id, channel_name, data, retain_flag, qos)
                         # check qos, only send pub ack if qos is 1
                         if qos == QOS.ONE:
                             response = PacketGenerator.generate_pub_res(status_code, pck_id)
                     else:
                         status_code, response_data = await peer.callbackWrapper.control_data_callback(peer.client_id, channel_name, data, peer.address, packet.protocol)
                         response = PacketGenerator.generate_pub_res(status_code, pck_id, response_data)
                         log_msg = ('Control Pub channel {0} from client {1} {2} : status {3}').format(channel_name, peer.client_id, peer.id, status_code)
                         logger.log_info(log_msg, peer.tag)
                 else:
                     status_code = StatusCode.INVALID_CHANNEL
                     response = PacketGenerator.generate_pub_res(status_code, pck_id)
                     msg = ('Pub INVALID channel {0} from client {1} {2}').format(channel_name, peer.client_id, peer.id)
                     logger.log_warning(msg, peer.tag)
                 
             #pushAck handler
             elif packet.packetType == PacketTypes.pushAck:
                 pck_id = PacketParser.get_arg(JSONKeys.packetId, packet.packetData)
                 await self.process_push_ack(pck_id, peer.client_id)
                 log_msg = ('PushAck for pck id {2} from client {0} {1}').format(peer.client_id, peer.id, pck_id)
                 logger.log_debug(log_msg, peer.tag)
             #sub handler
             elif packet.packetType == PacketTypes.sub:
                 channel_name = PacketParser.get_arg(JSONKeys.channelName, packet.packetData)
                 persistent_flag = PacketParser.get_arg(JSONKeys.persistent, packet.packetData, False)
                 channel_valid, channel_name = self.is_channel_valid(channel_name)
                 if channel_valid:
                     status_code = await peer.callbackWrapper.validate_sub_callback(peer.client_id, channel_name, persistent_flag, peer.address, packet.protocol)
                 else:
                     status_code = StatusCode.INVALID_CHANNEL
                 if status_code == StatusCode.OK:
                     status_code = await self.sub(peer.client_id, channel_name, persistent_flag)
                 response = PacketGenerator.generate_sub_res(status_code, channel_name)
                 if status_code != StatusCode.OK:
                     log_msg = ('Sub FAILED channel {0} with persistent {4} from client {1} {2} : status {3}').format(channel_name, peer.client_id, peer.id, status_code, persistent_flag)
                     logger.log_warning(log_msg, peer.tag)
                 else:
                     log_msg = ('Sub OK channel {0} with persistent {3} from client {1} {2}').format(channel_name, peer.client_id, peer.id, persistent_flag)
                     logger.log_debug(log_msg, peer.tag)
             #unsub handler
             elif packet.packetType == PacketTypes.unsub:
                 channel_name = PacketParser.get_arg(JSONKeys.channelName, packet.packetData)
                 channel_valid, channel_name = self.is_channel_valid(channel_name)
                 if channel_valid:
                     status_code = await peer.callbackWrapper.validate_unsub_callback(peer.client_id, channel_name, peer.address, packet.protocol)
                 else:
                     status_code = StatusCode.INVALID_CHANNEL
                 if status_code == StatusCode.OK:
                     status_code = await self.unsub(peer.client_id, channel_name)
                 response = PacketGenerator.generate_unsub_res(status_code, channel_name)
                 if status_code != StatusCode.OK:
                     log_msg = ('Unsub FAILED channel {0} from client {1} {2} : status {3}').format(channel_name, peer.client_id, peer.id, status_code)
                     logger.log_warning(log_msg, peer.tag)
                 else:
                     log_msg = ('Unsub OK channel {0} from client {1} {2}').format(channel_name, peer.client_id, peer.id)
                     logger.log_debug(log_msg, peer.tag)
             #hb handler
             elif packet.packetType == PacketTypes.hb:
                 await self.heartbeat(peer.client_id)
                 log_msg = ('Heartbeat from client {0} {1}').format(peer.client_id, peer.id)
                 logger.log_debug(log_msg, peer.tag)
                 if peer.client_id != None:
                     response = PacketGenerator.generate_heartbeat_res()
         else:
             logger.log_info('WARNING: access without connecting from peer ' + str(peer.id), 'create_response')
             response = None
     return (response, data)