Skip to content

Commit ae54ac4

Browse files
committed
fixes issues 65 and 66
1 parent a62e401 commit ae54ac4

File tree

3 files changed

+138
-3
lines changed

3 files changed

+138
-3
lines changed

src/README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/ambianic/peerjs-python)
2+
3+
# peerjs-python
4+
5+
Python port of [PeerJS](https://github.com/peers) client.
6+
- Tracked in issue [#160](https://github.com/peers/peerjs/issues/610) of the official PeerJS project.
7+
8+
Enables [Progressive Web Apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps) to discover and pair directly with Python apps using secure, browser supported [WebRTC](https://webrtc.org/) protocol.
9+
10+
## Additional features:
11+
12+
- *HTTP Proxy* over WebRTC data channel. It allows PeerJS browser clients to make remote REST requests over WebRTC to a local REST API running behind a firewall.
13+
- *Plug-and-play* functionality that allows seamless Airdrop-like pairing between peers running on the same local network.
14+
15+
See Ambianic UI [PNP module](https://github.com/ambianic/ambianic-ui/blob/master/src/store/pnp.js) for a real-world example how PeerJS Python is used with PnP and HTTP Proxy.
16+
17+
## Dependencies
18+
19+
Uses [aiortc](https://github.com/aiortc/aiortc) as Python WebRTC provider. This requires installing a few native dependencies for audio/video media processing.
20+
21+
On Debian/Ubuntu run:
22+
```
23+
apt install libavdevice-dev libavfilter-dev libopus-dev libvpx-dev pkg-config libsrtp2-dev
24+
```
25+
On OS X run:
26+
```
27+
brew install ffmpeg opus libvpx pkg-config
28+
```
29+
30+
## Motivation
31+
32+
This project was originally motivated while searching for a way to:
33+
- Connect a Progressive Web App ([Ambianic UI](https://github.com/ambianic/ambianic-ui)) directly and securely to an edge device ([Ambianic Edge](https://github.com/ambianic/ambianic-edge)) running Python app on a Raspberry Pi behind a home Internet router.
34+
35+
[This article in WebRTCHacks](https://webrtchacks.com/private-home-surveillance-with-the-webrtc-datachannel/) provides more insight into the background of this project.
36+
37+
## Main requirements
38+
39+
- Easy Airdrop-like plug and play discovery and pairing between web app and edge devices.
40+
- Direct peer-to-peer connectivity to minimize:
41+
- latency
42+
- architecture complexity
43+
- costs associated with traffic and hosting of tunneling servers
44+
- exposure to public server security attacks
45+
- Support for:
46+
- Secure connections
47+
- Bi-directional data-channel
48+
- Low latency audio/video media streaming
49+
- Bi-directional live audio/video media
50+
- Rely only on [standard](https://www.w3.org/TR/webrtc/) broadly supported web browser features.
51+
- Stable mobile device support (iOS, Android, Raspberry Pi)
52+
- Stable desktop OS support (Windows, Mac OS, Linux)
53+
- No need for browser plug-ins
54+
- No intermediary cloud service providers to store and sync user data.
55+
- No tedious and complicated NAT setups of dynamic DNS with SSH tunnels between public IP servers and edge devices behind firewall.
56+
- High throughput and scalability via lightweight signaling service without a persistence layer.
57+
58+
## Project Status
59+
60+
Initial working prototype completed. PeerJS Python is now able to connect over WebRTC DataChannel to PeerJS in the browser and exchange messages.
61+
62+
- [x] Complete and test connectivity with signaling server (peerjs-server).
63+
- [x] Complete and test data channel connectivity with web app peers.
64+
- [x] Release initial version to PyPi.
65+
- [x] support for python 3.7 & python 3.8
66+
- [x] support for python 3.9 (see [dependency issue](https://github.com/ambianic/peerjs-python/issues/48))
67+
- [ ] >90% code coverage with CI tests.
68+
- [ ] Port media support.
69+
70+
71+
## Code Examples
72+
73+
A typical p2p session takes these steps:
74+
1. Establish signaling server session that enables peers to discover each other.
75+
2. Discover remote peer ID (either via signaling server room affinity or other means)
76+
3. Request connection to remote peer via signaling server
77+
4. Connect to remote peer via WebRTC ICE protocol.
78+
5. Exchange data or media with remote peer over p2p WebRTC connection.
79+
80+
The following code snippet shows the initial part of establishing a signaling server connection.
81+
82+
```
83+
options = PeerOptions(
84+
host=config['host'],
85+
port=config['port'],
86+
secure=config['secure'],
87+
token=new_token,
88+
config=RTCConfiguration(
89+
iceServers=[RTCIceServer(**srv) for srv in config['ice_servers']]
90+
)
91+
)
92+
peer = Peer(id=savedPeerId, peer_options=options)
93+
await peer.start()
94+
log.info('peer activated')
95+
_setPnPServiceConnectionHandlers(peer)
96+
```
97+
98+
Once a signaling server connection is established, a peer can request connection to another peer or listen for requests from a remote peer.
99+
The example snippet bellow shows the latter:
100+
101+
```
102+
@peer.on(PeerEventType.Connection)
103+
async def peer_connection(peerConnection):
104+
log.info('Remote peer trying to establish connection')
105+
_setPeerConnectionHandlers(peerConnection)
106+
```
107+
108+
After a p2p connection is established, a peer can receive and send application messages. The following snippet shows how a peer receives a message:
109+
110+
```
111+
@peerConnection.on(ConnectionEventType.Data)
112+
async def pc_data(data):
113+
log.debug('data received from remote peer \n%r', data)
114+
```
115+
116+
For a complete working example see [this file](https://github.com/ambianic/peerjs-python/blob/master/src/peerjs/ext/http-proxy.py).
117+
118+
119+
120+
## Other Related Open Source projects
121+
122+
There are several great projects that solve the problem of accessing IoT devices behind firewall via tunneling servers.
123+
124+
- [Python Proxy](https://github.com/qwj/python-proxy): Asynchronous tunnel proxy implemented in Python 3 asyncio.
125+
- [Proxy.py](https://github.com/abhinavsingh/proxy.py): HTTP proxy server written in Python.
126+
- [Inlets](https://github.com/inlets/inlets): Reverse proxy and service tunnel written in Go.
127+
- [Macchina.io](https://github.com/my-devices/sdk): IoT tunneling proxy written in C++.
128+
129+
A few popular p2p projects that use WebRTC:
130+
131+
- [Simple peer](https://github.com/feross/simple-peer)
132+
- [WebTorrent](https://webtorrent.io/)
133+
- [Ipfs](https://ipfs.io/)
134+
- [Matrix](https://matrix.org/)
135+

src/peerjs/peer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# from websockets import WebSocket, ConnectionClosed
55
import asyncio
66
import logging
7-
from dataclasses import dataclass
7+
from dataclasses import dataclass, field
88
from typing import Any, List
99
import traceback
1010

@@ -49,7 +49,7 @@ class PeerOptions:
4949
path: str = "/"
5050
key: str = PEER_DEFAULT_KEY
5151
token: str = None
52-
config: Any = util.defaultConfig
52+
config: Any = field(default_factory=lambda: util.defaultConfig)
5353
secure: bool = False
5454
pingInterval: int = 5 # ping to signaling server in seconds
5555

src/setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ classifiers =
2121
packages = find_namespace:
2222
python_requires = >=3.7
2323
install_requires =
24-
av>=8.0,<10.1
24+
av>=8.0
2525
aiortc>=0.9
2626
websockets>=8.1
2727
aiohttp>=3.6

0 commit comments

Comments
 (0)