diff --git a/onvif/client.py b/onvif/client.py index b0fab2a..e9d0ac6 100644 --- a/onvif/client.py +++ b/onvif/client.py @@ -146,7 +146,6 @@ def __init__( user, passwd, url, - client: AsyncClient, encrypt=True, no_cache=False, dt_diff=None, @@ -163,12 +162,11 @@ def __init__( user, passwd, dt_diff=dt_diff, use_digest=encrypt ) # Create soap client + client = AsyncClient(verify=_NO_VERIFY_SSL_CONTEXT, timeout=90) self.transport = ( - AsyncTransport(client=client, verify_ssl=_NO_VERIFY_SSL_CONTEXT) + AsyncTransport(client=client) if no_cache - else AsyncTransport( - client=client, verify_ssl=_NO_VERIFY_SSL_CONTEXT, cache=SqliteCache() - ) + else AsyncTransport(client=client, cache=SqliteCache()) ) settings = Settings() settings.strict = False @@ -209,7 +207,7 @@ def __init__( async def close(self): """Close the transport.""" - # The client is not closed, as it is shared with the camera + await self.transport.aclose() @staticmethod @safe_func @@ -306,7 +304,7 @@ def __init__( self._snapshot_uris = {} self._snapshot_client = AsyncClient(verify=_NO_VERIFY_SSL_CONTEXT) - self._service_client = AsyncClient(verify=_NO_VERIFY_SSL_CONTEXT, timeout=90) + self._background_tasks = set() async def update_xaddrs(self): """Update xaddrs for services.""" @@ -360,7 +358,8 @@ async def create_pullpoint_subscription(self): async def close(self): """Close all transports.""" await self._snapshot_client.aclose() - await self._service_client.aclose() + for service in self.services.values(): + await service.close() async def get_snapshot_uri(self, profile_token): """Get the snapshot uri for a given profile.""" @@ -449,6 +448,17 @@ def create_onvif_service(self, name, port_type=None): if existing_service: if existing_service.xaddr == xaddr: return existing_service + else: + # Close the existing service since it's no longer valid. + # This can happen when a new PullPointSubscription is created. + logger.debug( + "Closing service %s with %s", binding_key, existing_service.xaddr + ) + # Hold a reference to the task so it doesn't get + # garbage collected before it completes. + task = asyncio.create_task(existing_service.close()) + task.add_done_callback(self._background_tasks.remove) + self._background_tasks.add(task) self.services.pop(binding_key) logger.debug("Creating service %s with %s", binding_key, xaddr) @@ -458,7 +468,6 @@ def create_onvif_service(self, name, port_type=None): self.user, self.passwd, wsdl_file, - self._service_client, self.encrypt, no_cache=self.no_cache, dt_diff=self.dt_diff,