# AppRTC Demo Code ## Development Detailed information on devloping in the [webrtc](https://github.com/webrtc) github repo can be found in the [WebRTC GitHub repo developer's guide](https://docs.google.com/document/d/1tn1t6LW2ffzGuYTK3366w1fhTkkzsSvHsBnOHoDfRzY/edit?pli=1#heading=h.e3366rrgmkdk). Running AppRTC locally requires the [Google App Engine SDK for Python](https://cloud.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python) and [Grunt](http://gruntjs.com/). Detailed instructions for running on Ubuntu Linux are provided below. ### Installing Google App Engine SDK for Python on Linux Unzip the App Engine SDK file you downloaded [google_appengine_1.9.40.zip](https://storage.googleapis.com/appengine-sdks/featured/google_appengine_1.9.40.zip), for example: ``` unzip google_appengine_1.9.40.zip -d /var/www/destination_folder ``` There is no App Engine installation script that you need to run after unzipping the files. Add the google_appengine directory to your PATH: ``` export PATH=$PATH:/path/to/google_appengine/ ``` Make sure Python 2.7 is installed on your machine using the following command: ``` /usr/bin/env python -V ``` The output should look like this: Python 2.7.<number>. If Python 2.7 isn't installed, install it now using the installation instructions for your Linux distribution. ### Running on Ubuntu Linux Install grunt by first installing [npm](https://www.npmjs.com/). npm is distributed as part of nodejs. ``` sudo apt-get install nodejs sudo npm install -g npm ``` On Ubuntu 14.04 the default packages installs `/usr/bin/nodejs` but the `/usr/bin/node` executable is required for grunt. This is installed on some Ubuntu package sets; if it is missing, you can add this by installing the `nodejs-legacy` package, ``` sudo apt-get install nodejs-legacy ``` It is easiest to install a shared version of `grunt-cli` from `npm` using the `-g` flag. This will allow you access the `grunt` command from `/usr/local/bin`. More information can be found on [`gruntjs` Getting Started](http://gruntjs.com/getting-started). ``` sudo npm -g install grunt-cli ``` *Omitting the `-g` flag will install `grunt-cli` to the current directory under the `node_modules` directory.* Finally, you will want to install grunt and required grunt dependencies. *This can be done from any directory under your checkout of the [webrtc/apprtc](https://github.com/webrtc/apprtc) repository.* ``` npm install ``` On Ubuntu, you will also need to install the webtest package: ``` sudo apt-get install python-webtest ``` Before you start the AppRTC dev server and *everytime you update the source code you need to recompile the App Engine package by running, ``` grunt build ``` Start the AppRTC dev server from the `out/app_engine` directory by running the Google App Engine SDK dev server, ``` dev_appserver.py --host 0.0.0.0 --port 9090 ./out/app_engine ``` Then navigate to http://localhost:9090 in your browser (given it's on the same machine). ### Allow Secure HTTP Install Stunnel package using the code below: ``` apt-get install stunnel4 -y ```` Configure Stunnel - Stunnel configures itself using a file named "stunnel.conf" which by default is located in "/etc/stunnel". Create a "stunnel.conf" file in the "/etc/stunnel" directory: ``` sudo gedit /etc/stunnel/stunnel.conf ``` We’re going to be using a SSL certificate to identify ourselves to the server so we have to set the path to that certificate in "stunnel.conf" file using this line (We will create the certificate file in the next step): ``` cert = /etc/stunnel/stunnel.pem ``` Next we specify a service for use with Stunnel. It can be any of the services which use networking such as mail server, proxy server, etc. After setting a name for the service you’re going to use, you must tell Stunnel to listen on which port for that service. This can be any of the 65535 ports, as long as it’s not blocked by another service or firewall: ``` [https] accept = 433 ``` Then depending on the service you’re going to use the secure tunnel on, you must specify the port and IP address of that in the configuration file Basically Stunnel takes packets from a secure port and then forwards it to the port and IP address of the service you specified. Squid proxy by default runs on localhost and port 9090 so we have to tell Stunnel to forward accepted connections to that port: ``` connect = 127.0.0.1:9090 ``` So overall the `"stunnel.conf"` file must contain the lines below: ``` client = no [https] accept = 433 connect = 127.0.0.1:9090 cert = /etc/stunnel/stunnel.pem ``` Note: The `client = no` part isn't necessary, Stunnel by default is set to server mode. Step 5: Create SSL Certificates Stunnel uses SSL certificate to secure its connections, which you can easily create using the OpenSSL package: ``` openssl genrsa -out key.pem 2048 openssl req -new -x509 -key key.pem -out cert.pem -days 1095 sudo cat key.pem cert.pem >> sudo /etc/stunnel/stunnel.pem ``` Basically, the commands above is for creating a private key, creating a certificate using that key and combining the two of them into one files named "stunnel.pem" to use with Stunnel. Note: When creating the certificate, you will be asked for some information such as country and state, which you can enter whatever you like but when asked for "Common Name" you must enter the correct host name or IP address of your droplet (VPS). Also, enable Stunnel automatic startup by configuring the `"/etc/default/stunnel4"` file, enter command below to open the file in text editor: ``` gedit /etc/default/stunnel4 ``` And change `ENABLED` to 1: ``` ENABLED=1 ``` Finally, restart Stunnel for configuration to take effect, using this command: ``` /etc/init.d/stunnel4 restart ``` ### Testing All tests by running `grunt`. To run only the Python tests you can call, ``` grunt runPythonTests ``` ### Enabling Local Logging *Note that logging is automatically enabled when running on Google App Engine using an implicit service account.* By default, logging to a BigQuery from the development server is disabled. Log information is presented on the console. Unless you are modifying the analytics API you will not need to enable remote logging. Logging to BigQuery when running LOCALLY requires a `secrets.json` containing Service Account credentials to a Google Developer project where BigQuery is enabled. DO NOT COMMIT `secrets.json` TO THE REPOSITORY. To generate a `secrets.json` file in the Google Developers Console for your project: 1. Go to the project page. 1. Under *APIs & auth* select *Credentials*. 1. Confirm a *Service Account* already exists or create it by selecting *Create new Client ID*. 1. Select *Generate new JSON key* from the *Service Account* area to create and download JSON credentials. 1. Rename the downloaded file to `secrets.json` and place in the directory containing `analytics.py`. When the `Analytics` class detects that AppRTC is running locally, all data is logged to `analytics` table in the `dev` dataset. You can bootstrap the `dev` dataset by following the instructions in the [Bootstrapping/Updating BigQuery](#bootstrappingupdating-bigquery). ## BigQuery When running on App Engine the `Analytics` class will log to `analytics` table in the `prod` dataset for whatever project is defined in `app.yaml`. ### Schema `bigquery/analytics_schema.json` contains the fields used in the BigQuery table. New fields can be added to the schema and the table updated. However, fields *cannot* be renamed or removed. *Caution should be taken when updating the production table as reverting schema updates is difficult.* Update the BigQuery table from the schema by running, ``` bq update -t prod.analytics bigquery/analytics_schema.json ``` ### Bootstrapping Initialize the required BigQuery datasets and tables with the following, ``` bq mk prod bq mk -t prod.analytics bigquery/analytics_schema.json ``` ### Deployment In order to deploy your own AppRTC instance you need a TURN/ICE server and a signaling server, in addition to AppRTC itself. The signaling server (Collider) is part of this repository and can be found [here](https://github.com/webrtc/apprtc/tree/master/src/collider)) while the TURN server used is [rfc5766-turn-server](https://github.com/coturn/rfc5766-turn-server). Credentials and TURN server instances are provided by a [CEOD](https://github.com/juberti/computeengineondemand) service that generates TURN servers on demand in form of a JSON response. This means you need to either set-up a web server that returns TURN credentials and IP addresses (basically mimic the [CEOD](https://github.com/juberti/computeengineondemand) server) in a JSON response, or replace the [CEOD](https://github.com/webrtc/apprtc/blob/master/src/app_engine/constants.py#L15) details with your own TURN server provider details, and then change to [turn_url = constants.TURN_URL_TEMPLATE](https://github.com/webrtc/apprtc/blob/master/src/app_engine/apprtc.py#L275). You can test using your own TURN server by appending the ?ts=serverUrl parameter, details on AppRTC URL parameters can be found at https://appr.tc/params.html. ### References * [GCP: Using the Local Development Server ](https://cloud.google.com/appengine/docs/python/tools/using-local-server) * [Get access GAE dev app server in the local network](http://stackoverflow.com/questions/7534967/is-there-any-way-to-access-gae-dev-app-server-in-the-local-network) * [Access AppEngine SDK sites via local ip-address when localhost](http://stackoverflow.com/questions/2168409/can-access-appengine-sdk-sites-via-local-ip-address-when-localhost-works-just-fi) * [Set Up an SSL Tunnel Using Stunnel on Ubuntu](https://www.digitalocean.com/community/tutorials/how-to-set-up-an-ssl-tunnel-using-stunnel-on-ubuntu) ``` stunnel -d 443 -p /path/to/stunnel.pem -r localhost:9090 -f -P '' & ``` * [Stunnel HOWTO](https://www.stunnel.org/howto.html) * [Check opened/closed port on Ubuntu](http://askubuntu.com/questions/538208/how-to-check-opened-closed-port-on-my-computer) There's a few parameters to [`netstat`](http://manpages.ubuntu.com/netstat.8) that are useful for this : - `-l` or `--listening` shows only the sockets currently listening for incoming connection. - `-a` or `--all` shows all sockets currently in use. - `-t` or `--tcp` shows the tcp sockets. - `-u` or `--udp` shows the udp sockets. - `-n` or `--numeric` shows the hosts and ports as numbers, instead of resolving in dns and looking in /etc/services. You use a mix of these to get what you want. To know which port numbers are currently in use, use one of these: ``` netstat -atn # For tcp netstat -aun # For udp netstat -atun # For both ``` In the output all port mentioned are in use either listening for incoming connection or connected to a peer** all others are closed. TCP and UDP ports are 16 bits wide (they go from 1-65535) ** They can also be connecting/disconnecting from the peer. * [How to kill a process on a port on ubuntu](http://stackoverflow.com/questions/9346211/how-to-kill-a-process-on-a-port-on-ubuntu) * My onw solution: ``` sudo kill `sudo lsof -t -i:433` ``` or ``` sudo netstat -ltunp | grep :902 ``` * [Python Flask Skeleton for Google App Engine](https://github.com/GoogleCloudPlatform/appengine-flask-skeleton/tree/master/lib) * [https for localhost:8080](http://stackoverflow.com/questions/6029473/https-for-localhost8080) * [Only secure origins are allowed](https://github.com/jakearchibald/simple-serviceworker-tutorial/issues/6) * [WebRTC PermissionDeniedError getUserMedia on RTCMultiConnection](http://stackoverflow.com/questions/34305323/webrtc-permissiondeniederror-getusermedia-on-rtcmulticonnection) * [Record video from your web apps](https://developers.google.com/web/updates/2015/10/chrome-47-webrtc?hl=en) * [WebRTC samples MediaRecorder](https://webrtc.github.io/samples/src/content/getusermedia/record/) * [WebRTC samples](https://webrtc.github.io/samples/) * [GitHub: RecordingApp](https://github.com/niklasenbom/RecordingApp) * [GitHub: AppRTC Demo Code](https://github.com/webrtc/apprtc) * [GitHub: WebRTC code samples](https://github.com/webrtc/samples) * [Stream from canvas to peer connection](https://webrtc.github.io/samples/src/content/capture/canvas-pc/) * [Real time communication with WebRTC](https://codelabs.developers.google.com/codelabs/webrtc-web/) * [GitHub: Realtime communication with WebRTC](https://github.com/googlecodelabs/webrtc-web) * [GitHub: WebRTC Experiments](https://github.com/muaz-khan/WebRTC-Experiment) * [WebRTC Experiments](http://websync.somee.com/) * [GitHub: WebSync-Signaling](https://github.com/muaz-khan/WebSync-Signaling)