ソースを参照

Merge branch 'dev_20241205' of ssh://gitlab.fuxicarbon.com:1111/client_service/voice-gateway-service into dev_20241205

shanghui 3 ヶ月 前
コミット
335847d2f0
2 ファイル変更53 行追加56 行削除
  1. 4 2
      src/core/callcenter/cache.py
  2. 49 54
      src/core/voip/bot.py

+ 4 - 2
src/core/callcenter/cache.py

@@ -190,10 +190,12 @@ class Cache:
         key = CTI_AGENT_MANUAL_ANSWER%(saas_id, flow_id)
         return self.redis_handler.redis.set(key, "1", ex=60, nx=True)
 
-    def lock_register_per_hours(self, hour):
+    def lock_register_per_hours(self):
+        hour = datetime.now().strftime('%Y%m%d%H')
         key = BOT_REGISTER_PER_HOURS %hour
         return self.redis_handler.redis.get(key)
 
-    def set_register_per_hours(self, hour, expire=86400):
+    def set_register_per_hours(self, expire=86400):
+        hour = datetime.now().strftime('%Y%m%d%H')
         key = BOT_REGISTER_PER_HOURS %hour
         return self.redis_handler.redis.set(key, "1", ex=expire, nx=True)

+ 49 - 54
src/core/voip/bot.py

@@ -518,57 +518,37 @@ class BotAgent:
         self.dataHandleServer = DataHandleServer(app)
         threading.Thread(target=self.create_pjsua2, daemon=True).start()
 
-    def create_pjsua2(self):
-        # Create and initialize the library
-        ep_cfg = pj.EpConfig()
-        ep_cfg.uaConfig.threadCnt = 12
-        ep_cfg.uaConfig.mainThreadOnly = False
-        ep_cfg.uaConfig.maxCalls = 20
-        ep_cfg.uaConfig.maxAccounts = 20
-        ep_cfg.medConfig.noVad = True
-        ep_cfg.logConfig.level = 3
-        ep_cfg.logConfig.consoleLevel = 3
-        self.ep.libCreate()
-        self.ep.libInit(ep_cfg)
-
-        aud_dev_mgr = self.ep.audDevManager()
-        aud_dev_mgr.setNullDev()  # 使用虚拟音频设备(如果没有实际设备)
-        # Set up media configuration, particularly jitter buffer
-        media_cfg = pj.MediaConfig()
-        media_cfg.jbMinPre = 4  # Minimum pre-fetch frames
-        media_cfg.jbMaxPre = 16  # Maximum pre-fetch frames
-        media_cfg.noVad = True  # Disable Voice Activity Detection if needed
-        self.ep.medConfig = media_cfg  # Apply media config to endpoint
-
-        # Create SIP transport. Error handling sample is shown
-        sipTpConfig = pj.TransportConfig()
-        sipTpConfig.port = 30506
-        self.ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig)
-        # Start the library
-        self.ep.libStart()
-        self.create_account()
-
-        while not self.is_stopping:
-            registry.BOT_AGENT_LIVES.set(self.user_part_pool.qsize())
-            self.register_per_hours()
-            self.ep.libHandleEvents(100)
-
-    def create_account(self, recreate = False, timeout_sec=86400):
+    def create_pjsua2(self, timeout_sec=86400):
         start_time = time.time()
         try:
-            _hour = datetime.now().strftime('%Y%m%d%H')
-            self.cache.set_register_per_hours(_hour, expire=timeout_sec)
-            if recreate:
-                for k, v in self.accounts.items():
-                    try:
-                        v.shutdown()
-                    except:
-                        traceback.print_exc()
-                while not self.user_part_pool.empty():
-                    try:
-                        self.user_part_pool.get_nowait()
-                    except:
-                        pass
+            self.cache.set_register_per_hours(expire=timeout_sec - (60*3))
+            # Create and initialize the library
+            ep_cfg = pj.EpConfig()
+            ep_cfg.uaConfig.threadCnt = 12
+            ep_cfg.uaConfig.mainThreadOnly = False
+            ep_cfg.uaConfig.maxCalls = 20
+            ep_cfg.uaConfig.maxAccounts = 20
+            ep_cfg.medConfig.noVad = True
+            ep_cfg.logConfig.level = 3
+            ep_cfg.logConfig.consoleLevel = 3
+            self.ep.libCreate()
+            self.ep.libInit(ep_cfg)
+
+            aud_dev_mgr = self.ep.audDevManager()
+            aud_dev_mgr.setNullDev()  # 使用虚拟音频设备(如果没有实际设备)
+            # Set up media configuration, particularly jitter buffer
+            media_cfg = pj.MediaConfig()
+            media_cfg.jbMinPre = 4  # Minimum pre-fetch frames
+            media_cfg.jbMaxPre = 16  # Maximum pre-fetch frames
+            media_cfg.noVad = True  # Disable Voice Activity Detection if needed
+            self.ep.medConfig = media_cfg  # Apply media config to endpoint
+
+            # Create SIP transport. Error handling sample is shown
+            sipTpConfig = pj.TransportConfig()
+            sipTpConfig.port = 30506
+            self.ep.transportCreate(pj.PJSIP_TRANSPORT_UDP, sipTpConfig)
+            # Start the library
+            self.ep.libStart()
 
             for user_part in self.user_part_range:
                 acfg = pj.AccountConfig()
@@ -598,13 +578,17 @@ class BotAgent:
         finally:
             latency = time.time() - start_time
             registry.BOT_CREATE_ACCOUNT_LATENCY.observe(latency)
-            self.logger.info("create account latency: %.3fs", latency)
+            self.logger.info("create pjsua latency: %.3fs", latency)
+
+        while not self.is_stopping:
+            registry.BOT_AGENT_LIVES.set(self.user_part_pool.qsize())
+            self.register_per_hours()
+            self.ep.libHandleEvents(100)
 
     def register_per_hours(self):
-        _hour = datetime.now().strftime('%Y%m%d%H')
-        _lock = self.cache.lock_register_per_hours(_hour)
+        _lock = self.cache.lock_register_per_hours()
         if not _lock and len(self.accounts) == len(self.user_part_range):
-            self.create_account(recreate=True)
+            self.restart()
 
     def transfer(self, user_part, call_id, device_id, service_id='00000000000000000'):
         if self.acd_service:
@@ -617,7 +601,6 @@ class BotAgent:
                 break
             time.sleep(0.1)
 
-
     def hangup(self, user_part, reason="NORMAL_CLEARING", **sip_headers):
         call_op_param = pj.CallOpParam(True)
         call_op_param.statusCode = pj.PJSIP_SC_OK
@@ -683,8 +666,20 @@ class BotAgent:
         self.user_part_pool.put(user_part)
         self.logger.info("release, user_part :%d, pool.size :%d", user_part, self.user_part_pool.qsize())
 
+    def restart(self):
+        self.destroy()
+        self.is_stopping = False
+        threading.Thread(target=self.create_pjsua2, daemon=True).start()
+
     def destroy(self):
         self.is_stopping = True
+        try:
+            while not self.user_part_pool.empty():
+                self.user_part_pool.get_nowait()
+        except:
+            pass
+        self.accounts.clear()
+        self.calls.clear()
         # Destroy the library
         self.ep.libDestroy()