refactor: improve discover() to yield hubs as interrogated
- Use asyncio.Queue to yield hubs as they complete interrogation
- Interrogate hubs concurrently via asyncio.create_task
- Clean up receive task on cancellation
- Extract _interrogate_hub() as reusable static method
- Remove deprecated loop parameter
- Remove unnecessary duplicate discover send
Full Changelog: v0.5.2...v0.5.3