LineManage.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. from hub import methods, Global
  2. import asyncio
  3. import threading
  4. import traceback
  5. class LineManage(object):
  6. """"""
  7. line_dict = {} # {<line_id>: <ws>, <now_ts>}
  8. @classmethod
  9. def run_forever(cls):
  10. tasks = [cls.check_loop()]
  11. _loop = asyncio.new_event_loop()
  12. asyncio.set_event_loop(_loop)
  13. loop = asyncio.get_event_loop()
  14. loop.run_until_complete(asyncio.wait(tasks))
  15. @classmethod
  16. def run_background(cls, is_back_run=True):
  17. t1 = threading.Thread(target=cls.run_forever)
  18. t1.start()
  19. @classmethod
  20. async def check_loop(cls):
  21. # --- define ---
  22. # last_send_id = str()
  23. while True:
  24. try:
  25. # --- debug ---
  26. # methods.debug_log(f"LineManage.check_loop44", f"#run at {methods.now_string()} "
  27. # f"| {len(cls.line_dict.values())}")
  28. # await asyncio.sleep(3)
  29. # await asyncio.sleep(0.5)
  30. # --- get send_data ---
  31. # """
  32. # send_data = {
  33. # send_id: 数据id
  34. # send_list: 数据列表
  35. # }
  36. # """
  37. # send_data = Global.rdb.get_one(key='send_data')
  38. # send_data = db0.get_one(key='send_data')
  39. # --- check ---
  40. # if not send_data:
  41. # continue
  42. # --- check ---
  43. # send_id = send_data.get('send_id')
  44. # if not send_id:
  45. # continue
  46. # --- check ---
  47. # if send_id == last_send_id:
  48. # continue
  49. # --- check ---
  50. # send_list = send_data.get('send_list')
  51. # if send_list is None or len(send_list) == 0:
  52. # continue
  53. # --- debug ---
  54. # await asyncio.sleep(3)
  55. # await asyncio.sleep(0.5)
  56. # methods.debug_log(f"LineManage", f"m-74: run at {methods.now_string()} "
  57. # f"| send count is {len(send_list)} "
  58. # f"| online count is {len(cls.line_dict.values())}")
  59. # --- define ---
  60. now_ts = methods.now_ts()
  61. # --- check ---
  62. for username in list(cls.line_dict.keys()):
  63. try:
  64. # --- debug ---
  65. _ws, last_live_at, _id = cls.line_dict.get(username)
  66. methods.debug_log(f"LineManage.check_loop87", f"#username: {username}"
  67. f" | #last_live_at: {last_live_at}"
  68. f" | #now_ts: {now_ts}")
  69. # --- check 180s ---
  70. if now_ts - last_live_at >= 3 * 60:
  71. cls.line_dict.pop(username)
  72. # --- check ---
  73. # if not cls.check_line_is_live(line_id):
  74. # methods.debug_log(f"LineManage", f"m-56: websocket link broken.")
  75. # cls.line_dict.pop(line_id)
  76. # continue
  77. # --- send ---
  78. # """
  79. # send_list = [
  80. # {
  81. # base_face_uuid: 底库人脸id
  82. # snap_face_image: 抓拍人脸
  83. # base_face_image_path: 底库人脸路径
  84. # face_similarity: 相似度
  85. # }
  86. # ]
  87. # """
  88. # for data in send_list:
  89. #
  90. # # --- check ---
  91. # if data.get('snap_face_image') is None:
  92. # continue
  93. #
  94. # # --- define ---
  95. # """
  96. # send_dict = {
  97. # input_face_b64: 抓拍人脸图像
  98. # face_uuid: 人脸id
  99. # face_name: 人脸名称
  100. # known_face_b64: 底库人脸图像
  101. # face_similarity: 相似度
  102. # face_type_name_list: 人员类型
  103. # }
  104. # """
  105. # send_dict = dict(
  106. # input_face_b64=cls.image_to_b64(data.get('snap_face_image')),
  107. # # input_face_b64=str(),
  108. # known_face_b64=str(),
  109. # face_uuid=str(),
  110. # face_name=str(),
  111. # face_similarity=data.get('face_similarity'),
  112. # face_type_name_list=list(),
  113. # )
  114. #
  115. # # --- fill input_face_b64 ---
  116. # # snap_face_image_path = data.get('snap_face_image_path')
  117. # # if snap_face_image_path and methods.is_file(snap_face_image_path):
  118. # # frame = cv2.imread(snap_face_image_path)
  119. # # if frame is not None:
  120. # # _, image = cv2.imencode('.jpg', frame)
  121. # # base64_data = base64.b64encode(image) # byte to b64 byte
  122. # # s = base64_data.decode() # byte to str
  123. # # send_dict['input_face_b64'] = f'data:image/jpeg;base64,{s}'
  124. #
  125. # # --- fill known_face_b64 ---
  126. # base_face_image_path = data.get('base_face_image_path')
  127. # if base_face_image_path and methods.is_file(base_face_image_path):
  128. # frame = cv2.imread(base_face_image_path)
  129. # if frame is not None:
  130. # _, image = cv2.imencode('.jpg', frame)
  131. # base64_data = base64.b64encode(image) # byte to b64 byte
  132. # s = base64_data.decode() # byte to str
  133. # send_dict['known_face_b64'] = f'data:image/jpeg;base64,{s}'
  134. #
  135. # # --- fill face_uuid and face_name ---
  136. # """
  137. # Face: 陌生人脸表
  138. # Face.face_name: 人脸名称
  139. # """
  140. # face_uuid = data.get('base_face_uuid')
  141. # if face_uuid:
  142. # send_dict['face_uuid'] = face_uuid
  143. # face = Global.mdb.get_one_by_id('Face', face_uuid)
  144. # if face and face.get('face_name'):
  145. # send_dict['face_name'] = face.get('face_name')
  146. #
  147. # # --- fill face_type_name_list ---
  148. # face_type_uuid_list = face.get('face_type_uuid_list')
  149. # if face_type_uuid_list:
  150. # send_dict['face_type_name_list'] = [face_type_name_dict.get(i)
  151. # for i in face_type_uuid_list
  152. # if face_type_name_dict.get(i)]
  153. #
  154. # # --- send ---
  155. # # methods.debug_log(f"LineManage", f"m-153: send_dict is {send_dict}")
  156. # line = cls.line_dict.get(line_id)
  157. # send_json = methods.json_dumps(send_dict)
  158. # await line.send_text(send_json)
  159. # # methods.debug_log(f"LineManage",
  160. # # f"m-161: end at {datetime.datetime.now().strftime('%H:%M:%S.%f')}")
  161. # # await asyncio.sleep(0.1)
  162. except Exception as exception:
  163. # --- check ---
  164. if not cls.check_line_is_live(username):
  165. cls.line_dict.pop(username)
  166. if exception.__class__.__name__ == 'RuntimeError':
  167. methods.debug_log(f"LineManage.check_loop194", f"d2: {cls.get_line_state()}")
  168. else:
  169. methods.debug_log("LineManage.check_loop194", f"#e: {exception.__class__.__name__}")
  170. methods.debug_log("LineManage.check_loop194", f"#t: {traceback.format_exc()}")
  171. # --- debug ---
  172. methods.debug_log(f"LineManage.check_loop198", f"wait 1 minutes check again")
  173. await asyncio.sleep(60)
  174. # await asyncio.sleep(60)
  175. # await asyncio.sleep(60)
  176. except Exception as exception:
  177. methods.debug_log(f"LineManage.check_loop208", f"#e: {exception.__class__.__name__}")
  178. methods.debug_log(f"LineManage.check_loop208", f"#t: {traceback.format_exc()}")
  179. methods.debug_log(f"LineManage.check_loop208", f"wait 1 minutes try again!")
  180. await asyncio.sleep(60)
  181. @classmethod
  182. def get_line_total(cls):
  183. count = 0
  184. for k, v in cls.line_dict.items():
  185. count += 1
  186. return count
  187. @classmethod
  188. def check_line_is_live(cls, line_id):
  189. d1 = {
  190. 0: 'CONNECTING',
  191. 1: 'CONNECTED',
  192. 2: 'DISCONNECTED',
  193. }
  194. _ws, _, _ = cls.line_dict.get(line_id)
  195. if _ws and d1.get(_ws.client_state.value) != 'DISCONNECTED':
  196. return True
  197. else:
  198. return False
  199. @classmethod
  200. def get_line_state(cls):
  201. d1 = {
  202. 0: 'CONNECTING',
  203. 1: 'CONNECTED',
  204. 2: 'DISCONNECTED',
  205. }
  206. d2 = dict() # {<line_id>: <state>}
  207. for line_id, line in cls.line_dict.items():
  208. state = d1.get(line.client_state.value)
  209. _id = line_id[-6:]
  210. d2[_id] = state
  211. return d2
  212. # @staticmethod
  213. # def image_to_b64(image):
  214. # frame = numpy_method.to_array(image) # list to numpy array
  215. # _, image = cv2.imencode('.jpg', frame)
  216. # base64_data = base64.b64encode(image)
  217. # s = base64_data.decode()
  218. # return f'data:image/jpeg;base64,{s}'