Skip to content

Add WebSocket Transport Module in py-libp2p #585

@seetadev

Description

@seetadev

Project Details

Summary

This feature introduces WebSocket transport support to py-libp2p, enabling interoperability with other libp2p implementations (such as js-libp2p and go-libp2p) that commonly use /ip4/.../tcp/.../ws multiaddrs.

Background

To improve cross-implementation interoperability—particularly with js-libp2p—we propose adding WebSocket (/ws) transport support to py-libp2p. This will allow Python nodes to connect to peers over WebSockets, enabling use cases such as browser-to-backend communication and compatibility with peers behind firewalls or NATs where TCP may be blocked.

This module will implement WebSocket transport according to the libp2p transport specification and integrate with py-libp2p’s existing transport upgrader system.

🎯 Goals

  • Implement a WebSocket transport conforming to the libp2p Transport interface.
  • Enable py-libp2p nodes to dial and listen over WebSocket (/ws) addresses.
  • Achieve compatibility with the js-libp2p and go-libp2p ping protocol over WebSockets.

📦 Tasks

  • Use websockets or aiohttp (or other asyncio-compatible WS library)
  • Wrap WebSocket streams to satisfy libp2p’s RawConnection abstraction
  • Handle multiaddr parsing with /ws support
  • Update transport upgrader logic to support WebSocket negotiation
  • Add unit and integration tests with local js-libp2p node

✅ Acceptance Criteria

  • py-libp2p can dial a /ws multiaddr served by a js-libp2p node
  • Bi-directional communication via WebSocket stream works
  • All stream muxing and crypto protocols function over WebSocket transport

📚 References

Motivation

Many modern libp2p applications—especially those built with js-libp2p—rely on WebSocket (/ws) transport for communication, particularly in browser environments where raw TCP or QUIC access is restricted. Currently, py-libp2p lacks support for the WebSocket transport layer, which significantly limits its interoperability with these ecosystems.

Adding WebSocket support will:

  • ✅ Enable py-libp2p nodes to connect with browser-based js-libp2p peers
  • ✅ Allow use of /ip4/.../tcp/.../ws multiaddrs for cross-platform interop
  • ✅ Improve support for NAT traversal and firewall-friendly communication
  • ✅ Expand testing scenarios for the /ipfs/ping/1.0.0 protocol and beyond
  • ✅ Lay the groundwork for full WebRTC integration and browser-native networking in the future

Requirements

The WebSocket transport module should:

  1. Conform to the libp2p Transport Interface

    • Implement Transport and Listener abstractions compatible with py-libp2p.
  2. Dial over WebSocket Multiaddrs

    • Parse and handle multiaddrs that include the /ws protocol.
    • Initiate outbound WebSocket connections using valid libp2p multiaddrs (e.g., /ip4/127.0.0.1/tcp/15001/ws).
  3. Listen on WebSocket Multiaddrs

    • Allow the Python node to listen for incoming WebSocket connections.
    • Advertise multiaddrs with /ws suffix correctly via identify protocol.
  4. Wrap WebSocket Streams as libp2p Connections

    • Wrap WebSocket streams in a RawConnection-like abstraction that supports reading/writing raw bytes.
  5. Support Transport Upgrading

    • Enable use of existing security (e.g., noise) and muxing (e.g., mplex) protocols over WebSocket connections.
  6. Be Asynchronous and Non-blocking

    • Use Python's asyncio event loop to integrate with the rest of the py-libp2p runtime.
  7. Maintain Compatibility with js-libp2p and go-libp2p WebSocket Transports

    • Ensure payload framing, connection handshake, and ping protocol behave correctly with existing libp2p nodes.
  8. Include Test Coverage

    • Unit tests for dial and listen behavior.
    • Integration test with js-libp2p WebSocket node and /ipfs/ping/1.0.0.
  9. Gracefully Handle Connection Lifecycle

    • Implement timeouts, graceful shutdown, and error handling (e.g., malformed frames, dropped connections).
  10. Minimal Dependencies

    • Prefer widely-used async WebSocket libraries like websockets or aiohttp with minimal bloat.

Open questions

  1. WebSocket Library Choice

    • Should we use websockets for its lightweight async API, or aiohttp for more flexible HTTP/WebSocket handling?
    • Are there performance or dependency concerns with either?
  2. Multiaddr Parsing Support

    • Should /ws parsing be handled via a separate module or integrated directly into existing multiaddr parsing logic?
    • Do we need to support /wss (secure WebSocket) immediately, or defer to a later stage?
  3. Interoperability Testing

    • What baseline test matrix should we establish to ensure compatibility with js-libp2p and go-libp2p?
    • Should we require a test harness that dials multiple WebSocket variants (e.g., localhost, DNS, secured)?
  4. Transport Upgrader Integration

    • Are there special considerations for upgrading WebSocket streams to secure + multiplexed connections?
    • Does WebSocket framing introduce overhead that affects handshake steps?
  5. Use in Browser-to-Python Scenarios

    • How should we handle CORS or browser-specific behavior if we expect inbound connections from WebRTC-compatible frontends?
    • Is a minimal HTTP handshake required for compatibility with browser peers?
  6. Future Support for WebSocket Secure (/wss)

    • Should the current implementation scaffold support TLS now, or remain plain-text and revisit later?

Are you planning to do it yourself in a pull request ?

Maybe

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions