113 lines
3.7 KiB
Python
113 lines
3.7 KiB
Python
|
|
import time
|
||
|
|
import asyncio
|
||
|
|
from multiprocessing import Process
|
||
|
|
from aiortc import RTCIceCandidate, RTCPeerConnection, RTCSessionDescription
|
||
|
|
from openapi_client.rest import ApiException
|
||
|
|
from pprint import pprint
|
||
|
|
from aiortc import RTCPeerConnection, RTCSessionDescription
|
||
|
|
from aiortc.sdp import candidate_from_sdp, candidate_to_sdp
|
||
|
|
import uuid
|
||
|
|
import openapi_client
|
||
|
|
|
||
|
|
# Defining the host is optional and defaults to http://127.0.0.1:8080
|
||
|
|
# See configuration.py for a list of all supported configuration parameters.
|
||
|
|
configuration = openapi_client.Configuration(
|
||
|
|
host = "http://127.0.0.1:8080"
|
||
|
|
)
|
||
|
|
|
||
|
|
server_name="myserver"
|
||
|
|
service_name="http1"
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def serve(peernet, knock, server_name):
|
||
|
|
|
||
|
|
async def server_internal():
|
||
|
|
pc = RTCPeerConnection()
|
||
|
|
|
||
|
|
# Define our handlers
|
||
|
|
done = False
|
||
|
|
session = "%s" % uuid.uuid4()
|
||
|
|
|
||
|
|
@pc.on("datachannel")
|
||
|
|
def on_datachannel(channel):
|
||
|
|
@channel.on("message")
|
||
|
|
def on_message(message):
|
||
|
|
# Process the message, and send a response
|
||
|
|
channel.send("pong" + message[4:])
|
||
|
|
|
||
|
|
@pc.on("connectionstatechange")
|
||
|
|
async def on_connectionstatechange():
|
||
|
|
if pc.connectionState == "failed":
|
||
|
|
done = True
|
||
|
|
await pc.close()
|
||
|
|
|
||
|
|
@pc.on("icecandidate")
|
||
|
|
async def on_icecandidate(candidate):
|
||
|
|
peernet.peer_net_service_create_ice_candidatge(session=knock.offer.name, ice_candidate={
|
||
|
|
"candidate": candidate_to_sdp(obj),
|
||
|
|
"sdpMid": obj.sdpMid,
|
||
|
|
"sdpLineIndex": obj.sdpMLineIndex,
|
||
|
|
})
|
||
|
|
|
||
|
|
|
||
|
|
# Add the remote offer
|
||
|
|
offer = RTCSessionDescription(sdp=knock.offer.sdp, type="offer")
|
||
|
|
await pc.setRemoteDescription(offer)
|
||
|
|
# Create an answer
|
||
|
|
answer = await pc.createAnswer()
|
||
|
|
await pc.setLocalDescription(answer)
|
||
|
|
# Send the answer
|
||
|
|
session_id = "%s" % uuid.uuid4()
|
||
|
|
knock.answer = {
|
||
|
|
"name": session_id,
|
||
|
|
"sdp": answer.sdp,
|
||
|
|
"sdpType": answer.type,
|
||
|
|
}
|
||
|
|
peernet.peer_net_service_update_knock(server_name, service_name, knock.name, knock2=knock)
|
||
|
|
|
||
|
|
while not done:
|
||
|
|
resp = peernet.peer_net_service_claim_ice_candidates(session_id)
|
||
|
|
if resp.ice_candidates != None:
|
||
|
|
time.sleep(1)
|
||
|
|
continue
|
||
|
|
for candidate in resp.ice_candidates:
|
||
|
|
ice_candidate = candidate_from_sdp(candidate.candidate)
|
||
|
|
ice_candidate.sdpMid = candidate.sdpMid
|
||
|
|
ice_candidate.sdpMLineIndex = candidate.sdpLineIndex
|
||
|
|
await pc.addIceCandidate(candidate)
|
||
|
|
coro = server_internal()
|
||
|
|
|
||
|
|
# run event loop
|
||
|
|
loop = asyncio.get_event_loop()
|
||
|
|
try:
|
||
|
|
loop.run_until_complete(coro)
|
||
|
|
except KeyboardInterrupt:
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Enter a context with an instance of the API client
|
||
|
|
with openapi_client.ApiClient(configuration) as api_client:
|
||
|
|
# Create an instance of the API class
|
||
|
|
peernet = openapi_client.PeerNetServiceApi(api_client)
|
||
|
|
|
||
|
|
resp = peernet.peer_net_service_create_server(server={
|
||
|
|
"name": server_name,
|
||
|
|
"rooms": ["room1"],
|
||
|
|
"services": [
|
||
|
|
{
|
||
|
|
"name": service_name,
|
||
|
|
"protocol": "http",
|
||
|
|
"version": "1.0",
|
||
|
|
},
|
||
|
|
],
|
||
|
|
})
|
||
|
|
|
||
|
|
while True:
|
||
|
|
print("Checking for knocks")
|
||
|
|
resp = peernet.peer_net_service_list_knocks(server=server_name, service=service_name)
|
||
|
|
for knock in resp.knocks:
|
||
|
|
print("Processing %s", knock)
|
||
|
|
p = Process(target=serve, args=(peernet, knock, server_name))
|
||
|
|
p.start()
|
||
|
|
time.sleep(5)
|