Skip to content

Add AsyncIO Support for DCC Connection Handling#239

Open
smeinecke wants to merge 5 commits into
jaraco:mainfrom
smeinecke:bug/dcc-aio
Open

Add AsyncIO Support for DCC Connection Handling#239
smeinecke wants to merge 5 commits into
jaraco:mainfrom
smeinecke:bug/dcc-aio

Conversation

@smeinecke
Copy link
Copy Markdown

@smeinecke smeinecke commented Feb 15, 2025

While developing with this library, I noticed that DCC connections are not managed using the asyncio library, which causes issues with DCC handling when using the asynchronous (AIO) version of the library.

This pull request introduces the following changes:

Core asyncio DCC support:

  • Added a DCCProtocol class for asyncio-based DCC connections
  • Added an AioDCCConnection class with full async connect/listen/disconnect lifecycle
  • Added dcc_connection_class in the AIO Reactor
  • Fixed naming: AIODCCConnectionAioDCCConnection for consistency

Passive DCC listen with port configurability:

  • Implemented AioDCCConnection.listen() using asyncio.create_server()
  • Supports configurable port: specific int, (min, max) tuple range, or list of ports to try
  • Supports ipv6=True parameter
  • Graceful fallback: tries each port until one binds, raises DCCConnectionError if all fail
  • DCCProtocol.connection_made() handles passive accept, captures peer info, fires dcc_connect event, and closes the listening server after a single connection
  • disconnect() properly cleans up both the server and transport

DCC CHAT support:

  • Added privmsg() method to AioDCCConnection for DCC CHAT sessions (auto-newline for chat, raw for other types)
  • Removed outdated "DCC chat has not yet been implemented" limitation from docstring

Example scripts:

  • scripts/dccsend-aio.py — passive DCC file sender using listen() with port range fallback
  • scripts/dccreceive-aio.py — active DCC file receiver using connect()
  • scripts/dccchat-aio.py — asyncio DCC chat example

Tests:

  • Comprehensive test coverage for connect, disconnect, send_bytes, process_data
  • Tests for listen with specific port, port range, port list, and range fallback
  • Tests for connection_made, disconnect cleanup, and connect error handling
  • Tests for DCC chat and raw privmsg behavior

Stefan M added 2 commits February 15, 2025 16:31
- Add DCCProtocol class
- Add AIODCCConnection class
- Add dcc_connection_class in AIO Reactor

TODO: implement listen/passive DCC
smeinecke added 3 commits May 24, 2026 22:13
- Fix typo: rector -> reactor
- Use LineBuffer instead of DecodingLineBuffer for bytes compatibility
- Catch connection errors and re-raise as DCCConnectionError
- Guard disconnect() against missing transport
- Guard send_bytes() against unconnected state and rename bytes parameter
- Add AioSimpleIRCClient dcc_connect/dcc_listen overrides for async methods
- Add comprehensive tests for AioDCCConnection connect, disconnect,
  send_bytes, process_data, and error handling
- Add DCCProtocol.connection_made() to handle passive DCC connections
- Implement AioDCCConnection.listen() with configurable port/range
  * Supports single port int, (min,max) tuple range, or list of ports
  * Supports ipv6=True parameter
  * Tries each port until one binds, raises DCCConnectionError on failure
- Update AioDCCConnection.disconnect() to close listening server
- Remove NotImplementedError placeholders from process_data()
- Add tests for listen, ipv6, specific port, port range, port list,
  range fallback, connection_made, and disconnect cleanup
- Add example scripts dccsend-aio.py (passive) and dccreceive-aio.py (active)
- Remove "DCC chat has not yet been implemented" limitation from client_aio docstring
- Add explicit `privmsg` method to `AioDCCConnection` for DCC CHAT sessions
- Add tests for DCC chat and raw privmsg behavior
- Add dccchat-aio.py example script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant