Literature Survey and Existing Solutions

Updated Nov 18, 2025

Before detailing the proposed design, it is pertinent to survey existing WebSocket handling mechanisms within Falcon and other relevant Python web frameworks and libraries. This provides context and helps identify established patterns and potential areas for improvement.

2.1. Falcon's Native WebSocket Capabilities

Falcon's support for WebSockets is built upon the ASGI WebSocket Specification and is available in its ASGI applications.[^2] Developers can add WebSocket support to a route by implementing an async def on_websocket(self, req, websocket) responder method within a resource class.[^1] This method is invoked when a WebSocket handshake request is successfully routed.

The falcon.asgi.WebSocket object provided to this responder offers methods for managing the connection lifecycle, such as accept(), close(), receive_text(), receive_data(), send_text(), and send_data(). [^2] Falcon also handles events like lost connections by raising a WebSocketDisconnected exception. Middleware components and media handlers can be used to augment WebSocket flows, similar to regular HTTP requests.[^2]

However, Falcon's native support routes an entire WebSocket connection to a single on_websocket handler. For applications requiring dispatch based on incoming message types (e.g., in a chat application with different commands like 'send_message', 'user_typing', etc.), developers must implement this logic manually within the on_websocket method. This can lead to large, complex conditional structures that are difficult to maintain and test.

2.2. Starlette

Starlette, a lightweight ASGI framework, provides robust WebSocket support. It uses WebSocketRoute for defining WebSocket endpoints, which can be an async function or an ASGI class like WebSocketEndpoint.[^3] The WebSocketEndpoint class typically offers methods like on_connect, on_receive, and on_disconnect to handle different phases of the WebSocket lifecycle, although the specifics of WebSocketEndpoint are not fully detailed in the reviewed material.[^3] The starlette.websockets.WebSocket class itself provides comprehensive methods for interaction, including accept(), close(), various send_* and receive_* methods (for text, bytes, JSON), and iterators for messages.[^4] Starlette's routing is path-based; message content-based dispatch within an endpoint remains a manual task for the developer.

2.3. Django Channels

Django Channels extends Django to handle WebSockets and other protocols beyond HTTP, built on ASGI.[^5] It introduces concepts like Consumers (analogous to Django views but for WebSockets and other protocols) which handle the lifecycle of a connection (e.g., connect, disconnect, receive).[^6] Routing is managed by ProtocolTypeRouter (to distinguish between HTTP, WebSocket, etc.) and URLRouter (for path-based routing to consumers).[^5] A key feature of Channels is the "channel layer," an abstraction for inter-process communication (often backed by Redis), allowing different parts of an application, including background tasks, to send messages to WebSockets.[^5] While powerful, Django Channels is a comprehensive system deeply integrated with Django, representing a more heavyweight solution than what is typically sought for a Falcon extension.

2.4. FastAPI

FastAPI, built on Starlette, leverages Starlette's WebSocket capabilities.[^7] It provides a decorator, @app.websocket("/ws"), to define WebSocket endpoints.[^7] Similar to Falcon and Starlette's basic function endpoints, this decorator typically maps a path to a single asynchronous function that manages the entire WebSocket connection lifecycle, including accepting the connection, receiving messages in a loop, and sending responses.[^7] Message dispatch based on content within this function is a manual implementation detail.

2.5. `websockets` Library

The websockets library is a focused Python library for building WebSocket servers and clients, emphasizing correctness, simplicity, and performance.[^8] It is built on asyncio and provides a coroutine-based API. While excellent for implementing the WebSocket protocol itself (e.g., serve for servers, connect for clients), it is not a web framework extension and does not offer higher-level routing or integration with framework components like Falcon's resources or request objects.[^8] Its primary goal is protocol implementation rather than framework-level application structure.

2.6. Gap Analysis and Opportunity

The survey reveals that while Falcon has basic ASGI WebSocket support, it lacks a dedicated mechanism for structured message routing and handling within a WebSocket connection that is analogous to its HTTP request handling. Frameworks like Django Channels offer very comprehensive solutions but come with significant architectural overhead. Starlette and FastAPI provide clean WebSocket endpoint definitions but still require manual message dispatch logic within those endpoints.

This identifies a clear opportunity for a Falcon extension that:

  1. Provides a routing mechanism for incoming WebSocket messages based on their content (e.g., a 'type' field).

  2. Offers a class-based structure for WebSocket handlers, similar to Falcon's HTTP resources, promoting organization and reusability.

  3. Integrates a system for managing active connections to allow background workers to easily send messages to specific clients or groups of clients.

  4. Achieves this in a lightweight, Falcon-idiomatic manner, consistent with the framework's philosophy of minimalism and developer experience.

The proposed Falcon-Pachinko library aims to fill this gap.