-
Notifications
You must be signed in to change notification settings - Fork 2
/
TeleopServiceWebRTCModule.py
162 lines (133 loc) · 7.84 KB
/
TeleopServiceWebRTCModule.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
from opentera.services.modules.WebRTCModule import WebRTCModule
from opentera.services.ServiceConfigManager import ServiceConfigManager
import os
import subprocess
from twisted.internet import task, reactor
import threading
import sys
from urllib.parse import quote
import time
class TeleopServiceWebRTCModule(WebRTCModule):
def __init__(self, config: ServiceConfigManager, service=None):
# Default init
WebRTCModule.__init__(self, config)
self.service = service
def poll_signaling_server_process(self, process, port: int, key: str, owner: str, session_info: dict):
print('poll_signaling_server_process')
# This function is running on a thread.
while process.poll() is None:
stdout_line = process.stdout.readline()
# Check for signaling server ready
if stdout_line:
print(stdout_line)
if b'======== Running on http://0.0.0.0:' in stdout_line:
# The Base Service will receive this message and send invitations
print('Publish Ready!')
self.redis.publish('webrtc.' + key, 'Ready!')
print('poll_signaling_server_process - done!')
thread = threading.currentThread()
reactor.callFromThread(lambda: thread.join())
def launch_signaling_server(self, port, key, owner, session_info):
# Read specific configurations
executable_args = [
# sys.executable,
os.path.realpath(self.config.webrtc_config['executable']),
'-u',
self.config.webrtc_config['script'],
'--port=' + str(port),
'--password=' + str(key),
'--ice_servers=' + self.config.webrtc_config['ice_servers'],
'--static_folder=' + self.config.webrtc_config['static_folder']]
try:
process = subprocess.Popen(executable_args,
cwd=os.path.realpath(self.config.webrtc_config['working_directory']),
stdout=subprocess.PIPE)
# Signaling thread read
signaling_thread = threading.Thread(target=self.poll_signaling_server_process,
args=[process, port, key, owner, session_info])
# One more process
self.processList.append({'type': 'signaling_server',
'process': process,
'port': port,
'key': key,
'owner': owner,
'session_info': session_info,
'thread': signaling_thread})
self.logger.log_info(self.module_name, 'launch_signaling_server', executable_args, 'pid', str(process.pid))
print(self.module_name + ' - started signaling server process', process)
# Start thread (reading stdout)
signaling_thread.start()
return True
except OSError as e:
print(self.module_name + ' - error starting process:', e)
return False
def create_webrtc_session(self, session_info):
room_name = session_info['session_key']
owner_uuid = session_info['session_creator_uuid']
# make sure we kill sessions already started with this owner_uuid or room name
self.terminate_webrtc_session_with_owner_uuid(owner_uuid)
self.terminate_webrtc_session_with_room_name(room_name)
# Get next available port
port = self.get_available_port()
key = room_name
print(self.module_name + ' - Should create WebRTC session with name:', room_name, port, key,
session_info['session_parameters'])
if port:
user_info = 'unknown'
user_name = 'unknown'
if len(session_info['session_users']) > 0:
for user_uuid in session_info['session_users']:
# Get user info
user_response = self.service.get_from_opentera('/api/service/users',
{'user_uuid': user_uuid})
if user_response.status_code != 200:
return False, {'error': 'Unable to get user info.'}
# Currently only uses the last user's information to generate the url, this is a limitation of the api
user_info = user_response.json()
user_name = quote(user_info['user_firstname'] + ' ' + user_info['user_lastname'])
robot_device_subtype_string = 'unknown'
if len(session_info['session_devices']) > 0:
for robot_device in session_info['session_devices']:
# Get robot device info
device_response = self.service.get_from_opentera('/api/service/devices',
{'device_uuid': robot_device,
'with_device_type': True,
'with_device_subtype': True})
if device_response.status_code != 200:
return False, {'error': 'Unable to get device info.'}
# Currently only uses the last device's information to generate the url, this is a limitation of the api
device_info = device_response.json()
if not 'device_subtype' in device_info:
return False, {'error': 'Unable to get device subtype info.'}
robot_device_subtype_string = quote('default')
if device_info['device_subtype'] != None:
if 'device_subtype_name' in device_info['device_subtype']:
robot_device_subtype_string = quote(device_info['device_subtype']['device_subtype_name'])
url_users = 'https://' + self.config.webrtc_config['hostname'] + ':' \
+ str(self.config.webrtc_config['external_port']) \
+ '/webrtc_teleop/' + str(port) + '/#user?pwd=' \
+ key + '&port=' + str(port) + '&user=1' + '&robot=' + robot_device_subtype_string + '&name=' + user_name
url_participants = 'https://' + self.config.webrtc_config['hostname'] + ':' \
+ str(self.config.webrtc_config['external_port']) \
+ '/webrtc_teleop/' + str(port) + '/#participant?pwd=' + key \
+ '&port=' + str(port) + '&participant=1' + '&robot=' + robot_device_subtype_string
url_devices = 'https://' + self.config.webrtc_config['hostname'] + ':' \
+ str(self.config.webrtc_config['external_port']) \
+ '/webrtc_teleop/' + str(port) + '/socket.io?pwd=' \
+ key + '&port=' + str(port) + '&device=1' + '&robot=' + robot_device_subtype_string
# No need for parameters for signaling server, but will be useful to store session information
if self.launch_signaling_server(port=port, key=key, owner=owner_uuid,
session_info=session_info):
result = {'url_users': url_users,
'url_participants': url_participants,
'url_devices': url_devices,
'key': key,
'port': port,
'owner': owner_uuid
}
# Return url
return True, result
else:
return False, {'error': 'Process not launched.'}
else:
return False, {'error': 'No available port left.'}