Package: peerjs
peerjs-pythonPython port ofPeerJSclient.Tracked in issue#160of the official PeerJS project.EnablesProgressive Web Appsto discover and pair directly with Python apps using secure, browser supportedWebRTCprotocol.Additional features:HTTP Proxyover WebRTC data channel. It allows PeerJS browser clients to make remote REST requests over WebRTC to a local REST API running behind a firewall.Plug-and-playfunctionality that allows seamless Airdrop-like pairing between peers running on the same local network.See Ambianic UIPNP modulefor a real-world example how PeerJS Python is used with PnP and HTTP Proxy.DependenciesUsesaiortcas Python WebRTC provider. This requires installing a few native dependencies for audio/video media processing.On Debian/Ubuntu run:apt install libavdevice-dev libavfilter-dev libopus-dev libvpx-dev pkg-config libsrtp2-devOn OS X run:brew install ffmpeg opus libvpx pkg-configMotivationThis project was originally motivated while searching for a way to:Connect a Progressive Web App (Ambianic UI) directly and securely to an edge device (Ambianic Edge) running Python app on a Raspberry Pi behind a home Internet router.This article in WebRTCHacksprovides more insight into the background of this project.Main requirementsEasy Airdrop-like plug and play discovery and pairing between web app and edge devices.Direct peer-to-peer connectivity to minimize:latencyarchitecture complexitycosts associated with traffic and hosting of tunneling serversexposure to public server security attacksSupport for:Secure connectionsBi-directional data-channelLow latency audio/video media streamingBi-directional live audio/video mediaRely only onstandardbroadly supported web browser features.Stable mobile device support (iOS, Android, Raspberry Pi)Stable desktop OS support (Windows, Mac OS, Linux)No need for browser plug-insNo intermediary cloud service providers to store and sync user data.No tedious and complicated NAT setups of dynamic DNS with SSH tunnels between public IP servers and edge devices behind firewall.High throughput and scalability via lightweight signaling service without a persistence layer.Project StatusInitial working prototype completed. PeerJS Python is now able to connect over WebRTC DataChannel to PeerJS in the browser and exchange messages.Complete and test connectivity with signaling server (peerjs-server).Complete and test data channel connectivity with web app peers.Release initial version to PyPi.support for python 3.7 & python 3.8support for python 3.9 (seedependency issue)>90% code coverage with CI tests.Port media support.Code ExamplesA typical p2p session takes these steps:Establish signaling server session that enables peers to discover each other.Discover remote peer ID (either via signaling server room affinity or other means)Request connection to remote peer via signaling serverConnect to remote peer via WebRTC ICE protocol.Exchange data or media with remote peer over p2p WebRTC connection.The following code snippet shows the initial part of establishing a signaling server connection.options = PeerOptions(
        host=config['host'],
        port=config['port'],
        secure=config['secure'],
        token=new_token,
        config=RTCConfiguration(
            iceServers=[RTCIceServer(**srv) for srv in config['ice_servers']]
        )
    )
    peer = Peer(id=savedPeerId, peer_options=options)
    await peer.start()
    log.info('peer activated')
    _setPnPServiceConnectionHandlers(peer)Once a signaling server connection is established, a peer can request connection to another peer or listen for requests from a remote peer.
The example snippet bellow shows the latter:@peer.on(PeerEventType.Connection)
    async def peer_connection(peerConnection):
        log.info('Remote peer trying to establish connection')
        _setPeerConnectionHandlers(peerConnection)After a p2p connection is established, a peer can receive and send application messages. The following snippet shows how a peer receives a message:@peerConnection.on(ConnectionEventType.Data)
    async def pc_data(data):
        log.debug('data received from remote peer \n%r', data)For a complete working example seethis file.Other Related Open Source projectsThere are several great projects that solve the problem of accessing IoT devices behind firewall via tunneling servers.Python Proxy: Asynchronous tunnel proxy implemented in Python 3 asyncio.Proxy.py: HTTP proxy server written in Python.Inlets: Reverse proxy and service tunnel written in Go.Macchina.io: IoT tunneling proxy written in C++.A few popular p2p projects that use WebRTC:Simple peerWebTorrentIpfsMatrix