Почему этот код Python занимает 2 минуты, чтобы выйти, когда он не может подключиться к OBS software?
Я новичок в Python и мало что знаю об asyncio. Я хочу запустить этот скрипт, и если программное обеспечение OBS, к которому он пытается подключиться на 10.11.0.124, не работает, чтобы выйти из кода. Код делает это, но это займет 2 минуты, прежде чем он выйдет. Я не могу понять, почему он не выходит немедленно, когда он не может подключиться к программному обеспечению OBS, которое не работает на 10.11.0.124.
#! /usr/bin/python3
import asyncio
import urllib.request
import sys
import datetime
from obswsrc import OBSWS
from obswsrc.requests import StartStopStreamingRequest
def logger(logmessage):
f = open("log.txt", "a")
f.write(str(datetime.datetime.now()) + " " + logmessage + "n")
f.close
async def main():
try:
async with OBSWS('10.11.0.124', 4444, "password") as obsws:
logger("Connection established.")
while True:
event = await obsws.event()
logger(str(format(event.type_name)))
if(format(event.type_name) == "StreamStarting"):
HitURLToLoadAsset = urllib.request.urlopen("http://10.11.0.159/api/v1/assets/control/asset&b0983c0918b94856900040d9a9e8bdbf").read()
logger(str(HitURLToLoadAsset))
if(format(event.type_name) == "StreamStopped"):
HitURLToLoadAsset = urllib.request.urlopen("http://10.11.0.159/api/v1/assets/control/asset&3b2fb67002364b269d0c2674a628533c").read()
logger(str(HitURLToLoadAsset))
logger("Connection terminated.")
except OSError:
logger("OBS IS NOT RUNNING")
except:
logger(str(sys.exc_info()[1]))
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
2 ответа:
Функция
OBSWS
имеет тайм-аут в две минуты, поскольку она использует модульwebsockets
внутренне и имеет тайм-аут по умолчанию в две минуты.Детальная разбивка:
async with OBSWS(...):
звонкиOBSWS.__init__
а затемawait
sOBSWS.__aenter__
.OBSWS.__init__
не делает ничего интересного, ноOBSWS.__aenter__
await
sOBSWS.connect
OBSWS.connect
await
swebsocket.connect
.websockets.connect
имеет несколько различных таймаутов, определенных с помощью ключевого слова аргументы. Он также ждет нескольких вещей. Это:
self._creating_connection
, определено здесь
- это использует
loop.create_connection
который имеет 60-секундный тайм-аут по умолчанию.- затем он вызывает
factory
который вызываетcreate_protocol
, который по умолчаниюklass
который по умолчаниюWebSocketClientProtocol
, какие подклассыWebSocketCommonProtocol
что, вероятно, не добавляет ничего нового перебои.protocol.handshake(...)
protocol.fail_connection()
в случае возникновения какого-либо исключения, которое действительно имеет место.Я не понимаю
asyncio
поэтому я просто остановился здесь; вероятно, где-то есть еще 60 секунд задержки, но если нет... возможно, компьютер был просто медленным.
Спасибо за помощь user4815162342 и wizzwizz4! Вот мое окончательное решение.
В итоге я согласился с предложением wizzwizz4 о разрыве строки соединения, чтобы я мог использовать asyncio.wait_for на нем.
Если кому-то интересно, что сам код должен смотреть OBS, и когда потоковая передача запускается, перейдите к смене актива на Screenly OSE, чтобы отобразить поток RTMP. Когда поток прекратился переключения между различными активами на Screenly ОСЭ.
#! /usr/bin/python3 import asyncio import urllib.request import sys import datetime from obswsrc import OBSWS from obswsrc.requests import StartStopStreamingRequest def logger(logmessage): f = open("log.txt", "a") f.write(str(datetime.datetime.now()) + " " + logmessage + "\n") f.close async def main(): try: obsws = OBSWS('10.11.0.124', 4444, "password") # if no response from OBS in 30 seconds EXIT await asyncio.wait_for(obsws.connect(), timeout=30) logger("Connection established.") while True: event = await obsws.event() logger(str(format(event.type_name))) if(format(event.type_name) == "StreamStarting"): HitURLToLoadAsset = urllib.request.urlopen("http://10.11.0.159/api/v1/assets/control/asset&b0983c0918b94856900040d9a9e8bdbf").read() logger(str(HitURLToLoadAsset)) if(format(event.type_name) == "StreamStopped"): HitURLToLoadAsset = urllib.request.urlopen("http://10.11.0.159/api/v1/assets/control/asset&3b2fb67002364b269d0c2674a628533c").read() logger(str(HitURLToLoadAsset)) except asyncio.TimeoutError: logger("OBS NOT RUNNING-- TIMEOUT!") except OSError: logger("OBS IS NOT RUNNING") except: logger(str(sys.exc_info()[1])) finally: await obsws.close() logger("Connection terminated.") loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()