Browse Source

调试语音机器人重启之后大于一定时间不能呼通问题

刘威 5 months ago
parent
commit
7b5ef7b240

+ 4 - 2
src/core/callcenter/esl/client.py

@@ -18,6 +18,7 @@ import src.core.callcenter.esl.handler as event_handler
 from src.core.callcenter.esl.constant.sip_header_constant import sipHeaderHoldMusic
 from src.core.callcenter.enumeration import CallCause
 from src.core.callcenter.esl.handler.default_esl_event_handler import DefaultEslEventHandler
+from src.core.voip.bot import BotAgent
 
 
 class InboundClient:
@@ -27,8 +28,9 @@ class InboundClient:
         self.thread_num = 32
         self.is_stopping = False
         self.logger = logger
+        self.bot_agent = BotAgent(logger)
         self.handler_table = self.scan_esl_event_handlers()
-        self.default_event_handler = DefaultEslEventHandler(self, self.logger)
+        self.default_event_handler = DefaultEslEventHandler(self, self.bot_agent, self.logger)
         self.host, self.port, self.password = '192.168.124.6', '8021', '4918257983818884358'
         self.executors = {x: concurrent.futures.ThreadPoolExecutor(max_workers=1) for x in range(self.thread_num)}
 
@@ -52,7 +54,7 @@ class InboundClient:
         handlers = {}
         for _cls in classes:
             items = handlers.get(_cls._esl_event_name, [])
-            items.append(_cls(self, self.logger))
+            items.append(_cls(self, self.bot_agent, self.logger))
             handlers[_cls._esl_event_name] = items
         return handlers
 

+ 2 - 2
src/core/callcenter/esl/handler/channel_answer_handler.py

@@ -15,8 +15,8 @@ from src.core.callcenter.model import CallInfo, DeviceInfo, NextCommand
 @EslEventName(CHANNEL_ANSWER)
 class ChannelAnswerHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         call_id = EslEventUtil.getCallId(event)

+ 2 - 2
src/core/callcenter/esl/handler/channel_bridge_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_BRIDGE)
 class ChannelBridgeHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/channel_hangup_complete_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_HANGUP_COMPLETE)
 class ChannelHangupCompleteHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 4 - 2
src/core/callcenter/esl/handler/channel_hangup_handler.py

@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 # encoding:utf-8
 
+import json
 import src.core.callcenter.cache as Cache
 from src.core.callcenter.acd import AcdService
 from src.core.callcenter.call import CallService
@@ -16,12 +17,13 @@ from src.core.callcenter.model import CallInfo, DeviceInfo, NextCommand
 @EslEventName(CHANNEL_HANGUP)
 class ChannelHangupHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
         self.acd_service = AcdService(inbound_client, logger)
         self.call_service = CallService(inbound_client, logger)
 
     def handle(self, address, event, coreUUID):
+        self.logger.info(json.loads(event.serialize('json')))
         call_id = EslEventUtil.getCallId(event)
         if not call_id:
             self.logger.info("call_id is null")

+ 4 - 6
src/core/callcenter/esl/handler/channel_park_handler.py

@@ -5,15 +5,13 @@ import json
 from src.core.callcenter.esl.annotation import EslEventName
 from src.core.callcenter.esl.constant.event_names import CHANNEL_PARK
 from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
-from src.core.voip.bot import BotAgent
 
 
 @EslEventName(CHANNEL_PARK)
 class ChannelParkHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
-        self.bot = BotAgent(logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         service = event.getHeader("variable_service")
@@ -24,8 +22,8 @@ class ChannelParkHandler(EslEventHandler):
 
     def process_fxo_calling(self, event):
         kwargs = json.loads(event.serialize('json'))
-        destination = self.bot.register(**kwargs)
-        # destination = '1000'
+        destination = self.bot_agent.register(**kwargs)
+        # destination = '1001'
         # 获取通话的 UUID
         call_uuid = event.getHeader("Unique-ID")
         service = event.getHeader("variable_service")

+ 2 - 2
src/core/callcenter/esl/handler/channel_progress_media_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(CHANNEL_PROGRESS_MEDIA)
 class ChannelProgressMediaHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/default_esl_event_handler.py

@@ -8,8 +8,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 
 class DefaultEslEventHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         # self.logger.info(json.loads(event.serialize('json')))

+ 2 - 2
src/core/callcenter/esl/handler/detected_tone_handler.py

@@ -10,8 +10,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(DETECTED_TONE)
 class DetectedToneHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/dtmf_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(DTMF)
 class DTMFHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 1
src/core/callcenter/esl/handler/esl_event_handler.py

@@ -5,8 +5,9 @@ from abc import ABC, abstractmethod
 
 
 class EslEventHandler(ABC):
-    def __init__(self, inbound_client, logger):
+    def __init__(self, inbound_client, bot_agent, logger):
         self.inbound_client = inbound_client
+        self.bot_agent = bot_agent
         self.logger = logger
 
     @abstractmethod

+ 2 - 2
src/core/callcenter/esl/handler/playback_stop_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(PLAYBACK_STOP)
 class PlaybackStopHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/callcenter/esl/handler/record_stop_handler.py

@@ -9,8 +9,8 @@ from src.core.callcenter.esl.handler.esl_event_handler import EslEventHandler
 @EslEventName(RECORD_STOP)
 class RecordStopHandler(EslEventHandler):
 
-    def __init__(self, inbound_client, logger):
-        super().__init__(inbound_client, logger)
+    def __init__(self, inbound_client, bot_agent, logger):
+        super().__init__(inbound_client, bot_agent, logger)
 
     def handle(self, address, event, coreUUID):
         pass

+ 2 - 2
src/core/datasource.py

@@ -117,10 +117,10 @@ class MysqlHandler:
 @singleton
 class RedisHandler:
 
-    def __init__(self, host='', port=6379, db=0, password='^YHN&UJM'):
+    def __init__(self, host='192.168.124.6', port=6379, db=0, password='^YHN&UJM'):
         try:
             # host = '10.0.0.24'
-            host = RADIS_HOST
+            # host = RADIS_HOST
             self.redis = StrictRedis(
                 connection_pool=ConnectionPool(host=host, port=port, db=db, password=password))
         except Exception as e:

+ 1 - 1
src/core/server.py

@@ -11,5 +11,5 @@ if __name__ == '__main__':
     # out = OutboundClient()
     # threading.Thread(target=out.start, args=()).start()
     # threading.Thread(target=on.start, args=()).start()
-    socketio.run(app, host='127.0.0.1', port=5000, allow_unsafe_werkzeug=True, debug=True)
+    socketio.run(app, host='0.0.0.0', port=5000, allow_unsafe_werkzeug=True, debug=True)
     # app.run(host='127.0.0.1', port=5000, debug=True)

+ 29 - 10
src/core/voip/bot.py

@@ -76,10 +76,12 @@ class Account(pj.Account):
         self.kwargs = kwargs
 
     def onRegState(self, prm):
-        print("***OnRegState: " + prm.reason)
+        ai = self.getInfo()
+        print("***OnRegState: " + prm.reason, ai.id,ai.isDefault,ai.uri,ai.regIsConfigured,ai.regIsActive,ai.regExpiresSec,ai.regStatus,ai.regStatusText,ai.regLastErr,ai.onlineStatus,ai.onlineStatusText)
 
     def onIncomingCall(self, prm):
-        print("***onIncomingCall: ", prm.callId, json.dumps(self.kwargs))
+        ai = self.getInfo()
+        print("***onIncomingCall: ", prm.callId, ai.id,ai.isDefault,ai.uri,ai.regIsConfigured,ai.regIsActive,ai.regExpiresSec,ai.regStatus,ai.regStatusText,ai.regLastErr,ai.onlineStatus,ai.onlineStatusText)
 
         call = MyCall(self.agent, self, self.user_part, prm.callId, **self.kwargs)
         call_op_param = pj.CallOpParam(True)
@@ -100,9 +102,10 @@ class MyCall(pj.Call):
         self.aud_med = None
         self.recorder = None
         self.player = None  # 用于播放录音的媒体播放器
-        from src.core.voip.asr import TestSt
-        self.asr = TestSt(call_id)  # 创建ASR实例
-        self.asr.start()  # 启动ASR线程
+        self.asr = None
+        # from src.core.voip.asr import TestSt
+        # self.asr = TestSt(call_id)  # 创建ASR实例
+        # self.asr.start()  # 启动ASR线程
 
     def onDtmfDigit(self, prm):
         digit = prm.digit
@@ -128,7 +131,7 @@ class MyCall(pj.Call):
         if call_info.state == pj.PJSIP_INV_STATE_DISCONNECTED:
             print("通话结束")
             # 远程挂机之后要将分机号回收
-            self.agent.unregister(self.user_part)
+            self.agent.release(self.user_part)
 
     def onCallMediaState(self, prm):
         call_info = self.getInfo()
@@ -191,7 +194,7 @@ class MyCall(pj.Call):
 
 class BotAgent:
 
-    def __init__(self, logger, user_part_range=range(1000, 1010), host="192.168.124.6", port="5060", password="slibra@#123456"):
+    def __init__(self, logger, user_part_range=range(1001, 1011), host="192.168.124.6", port="5060", password="slibra@#123456"):
         self.logger = logger
         self.user_part_range, self.host, self.port, self.password = user_part_range, host, port, password
         self.pool = queue.Queue(maxsize=len(user_part_range))
@@ -207,8 +210,8 @@ class BotAgent:
         ep_cfg.uaConfig.threadCnt = 1
         ep_cfg.uaConfig.mainThreadOnly = True
         ep_cfg.uaConfig.maxCalls = 8
-        ep_cfg.logConfig.level = 5
-        ep_cfg.logConfig.consoleLevel = 5
+        ep_cfg.logConfig.level = 4
+        ep_cfg.logConfig.consoleLevel = 4
         self.ep.libCreate()
         self.ep.libInit(ep_cfg)
 
@@ -229,6 +232,10 @@ class BotAgent:
             cred = pj.AuthCredInfo("digest", "*", f"{user_part}", 0, self.password)
             acfg.sipConfig.authCreds.append(cred)
 
+            acfg.regConfig.timeoutSec = 3600  # 注册超时时间(秒)
+            acfg.regConfig.retryIntervalSec = 10  # 重试间隔时间(秒)
+            acfg.regConfig.firstRetryIntervalSec = 10  # 首次重试间隔时间(秒)
+
             # Create the account
             acc = Account(self, user_part)
             acc.create(acfg)
@@ -254,9 +261,14 @@ class BotAgent:
 
     def register(self, **kwargs):
         user_part = self.pool.get()
-        self.logger.info('register, user_part :%d, args: %s', user_part, json.dumps(kwargs))
+        self.logger.info('register, user_part :%d, pool.size :%d', user_part, self.pool.qsize())
         acc = self.accounts.get(user_part)
         if acc:
+            # ps = pj.PresenceStatus()
+            # ps.status = pj.PJSUA_BUDDY_STATUS_ONLINE
+            # ps.activity = pj.PJRPID_ACTIVITY_AWAY
+            # ps.note = "Away"
+            # acc.setOnlineStatus(ps)
             # acc.setRegistration(renew=True)
             acc.kwargs = kwargs
         return user_part
@@ -279,6 +291,7 @@ class BotAgent:
         if element_in_queue(self.pool, user_part):
             return
         self.pool.put(user_part)
+        self.logger.info("release, user_part :%d, pool.size :%d", user_part, self.pool.qsize())
 
     def destroy(self):
         self.is_stopping = True
@@ -287,3 +300,9 @@ class BotAgent:
 
     def __del__(self):
         self.destroy()
+
+
+# if __name__ == '__main__':
+#     import logging
+#     logger = logging.getLogger('voip')
+#     bot = BotAgent(logger)

BIN
src/core/voip/incoming_call.wav