BrowserBasedViewing

UPV for Render Streaming

To connect UPV to UPV Web services there are two parts affected for running UPV in streaming mode, Watchdog and UPV itself.

The Watchdog component is used for controlling which models are provided to the user and how to deal with several instances running on one machine.
It uses the RenderStreaming section of UPV’s defaultConfig.upv to connect to the UPV Web Services.

Requirements

Hardware minimum:

  • CPU: quad core
  • RAM: 8GB
  • Windows Server 2016, 2019 or Windows 10 (1903 or newer)
  • Nvidia graphics card that supports hardware encoding.
    Alternatively software encoding can be configured s. below
  • Physical Display | Monitor

We recommend at least 4GB RAM, 4 CPU threads, 2 GB video memory for each user.

Example for 8 users concurrently:
-CPU 32 Threads, 32GB RAM and 16 GB of Video memory.

This will vary heavily based on the models streamed.

Installation

Install Files

  • Unzip BrowserBasedViewing_XX.zip so that you have; C:\BrowserBasedViewing\UPV
    C:\BrowserBasedViewing\Watchdog
  • Run C:\BrowserBasedViewing\Watchdog\win-x64\install.cmd” that will create
    • watchdog.json in BrowserBasedViewing\Watchdog\win-x64\Settings
    • defaultConfig.upv in BrowserBasedViewing\UPV

Edit UPV defaultConfig.upv

Set the maximum native resolution for (X; Y). If a client requests a larger size, it will be scaled to fit the aspect ratio.

Do not exceed the size of the connected display or dummy display adapter!

"MaxHorizontalResolution": 1920,
"MaxVerticalResolution": 1440,

Set the URL (UpvWebServicesUrl, with trailing ‘/signaling’) and the password (StreamingConfig / SignalingApiCredential) you have assigned during setup of UPV Web Services

"UrlSignaling": "https://myupvweb/signaling",
"SignalingApiCredential": "myapipassword",

Edit watchdog.json

The config is located under Watchdog\win-x64\Settings\watchdog.json.

Enter your local and remote model search paths. Local paths are scanned recursively
Set InstanceCount to the number of pre-loaded instances per model.

"ModelPaths": [
  {
    "Path": "file:///C:/MyModels/StreamingModels",
    "InstanceCount": 0
  },
  {
    "Path": "http://demo.universalplantviewer.com/demoPlant/6/0/",
    "InstanceCount": 0
  }
]

Set the total number of running instances and the ReservedInstanceCount.
This stands for blocking a certain number of instances for free usage but not pre-loading. That means if (MaxInstanceCount - ReservedInstanceCount) is reached, the remaining ReservedInstanceCount slots will not be used for pre-starting to avoid exhausting all MaxInstanceCount available instances by pre-starting.

"MaxInstanceCount": 5,
"ReservedInstanceCount": 1,

Decide whether to run UPV instances in background. We recommend this as you do not need an active, non-locked session to run the system. Thus you can logout from your remote desktop session and it will continue to work.

You cannot completely log off from server as a user session is needed to interactive applications to run under Windows.

You have to set the maximum resolutions to the available display size, s. above Edit UPV defaultConfig.upv.

"Batchmode": true,

Finish Setup

Start Watchdog\win-x64\run.cmd.

Open the URL you have set up for “UrlSignaling”: “https://myupvweb/signaling” in your browser. After authenticating yourself you should see a list of available models either locally at “C:\MyModels\StreamingModels” or at http://mymodels.com/demoPlant”.

Watchdog is a Windows Console application that has to be started manually or by a scheduler task.

Due to the standard Console app behaviour, make sure to have no text in the console selected as this will pause watchdog!

Firewall

Unlock a UDP port range between 50000 and 60000. Minimum 10 ports for each additional user 2 more.

The Streaming is using the webrtc technology and it automatically take ports. The server is communicating with the WebUPV and the Identity Server, so the ports 80, 443, 3000 and 44358 from the default settings should be unlocked, but this depends on your web server configuration.

Enhanced Configuration

defaultConfig.upv

The CommonSettings / RenderStreaming section contains some more settings aside from those discussed in Edit UPV defaultConfig.upv.

Global switch for enabling or disabling UPV render streaming at all (default is true).

"AutoConnect" = true

The duration in milliseconds to wait for terminating the 3D Viewer app: (default 2000).

"QuitAfterDisconnectDelay" = 2000

Currently software encoder provides more reliable quality, but this will change in the future.

Set this false only if you have a NVidia graphics card that supports hardware encoding. See section MaxInstanceCount above to learn more about session limitations as it is important to not exceed your maximum number of concurrent sessions.

Hardware encoding might produce faster rendering results while navigating but can occasionally lead to artefacts.

"UseSoftwareEncoder" = true

Time in seconds after which a client is disconnected automatically when there was no input activity at all. Mouse moves are considered as activity. Leave this out or set value to 0 to enable unrestricted sessions.

"MaxClientIdleTime"

Specifies if file uploads from browser clients are allowed. Default is false.

"BlockClientUploads" = false

Specifies if file downloads to browser clients are allowed. Default is false.

"BlockClientDownloads" = false

Enables receiving API commands via WebRTC data channel. The javascript frontend exports a method commandChannelHandler() for accessin class CommandChannelHandlerHandler that provides some methods to send and receive API commands. Default is false.

"AllowRemoteApiCommands" = true

If true, self-signed or other unsafe certificates will be trusted. Set this false in production!

"IgnoreCertificateErrors"

Set the threshold of GPU memory in MB at which a graphics adapter is considered as useful for streaming. This is used to suppress using onboard or other low level graphics adapters for rendering in UPV.

"MinGpuMemory": 2000

Watchdog

Expert settings aside from those discussed in Edit watchdog.json.

UPVInstance: Path to UPV executable.

"UPVInstance": "..\\..\\..\\UPV\\UniversalPlantViewer.exe"

Further arguments to be passed to UPV on launching. Useful are -width and -height when running non-batchmode or -monitor to force launching on a specific monitor.

"UPVArguments": "- monitor -width 800 -height 600",

“Expert” section.

If true, self-signed or other unsafe certificates will be trusted. Set this false in production!

"IgnoreCertificateErrors": true,

Duration in milliseconds how long to block a starting instance for a specific client if something went wrong. Recommended is twice the regular start time of the biggest model.

"StartInstanceTimeout": 60000

“Serilog” section.

Specify the log level as “Debug”, “Information”, “Warning” or “Error”.

"MinimumLevel": {
  "Default": "Debug",

The path to lgo file location, naming and rotation policy.

"WriteTo": [
  {
    "Name": "File",
    "Args": {
      "path": "../logs/Watchdog-.log",
      "rollingInterval": "Day",
      "outputTemplate": "{Timestamp:u} [{Level}] {Message}{NewLine}{Exception}"
  }

Model Role Configuration

When user roles have been defined on Identity server, some user restrictions to these roles can be defined to restrict loading models.

These restrictions are applied to GetModelList and PostStart endpoints in SignalingEntryController by ModelRoleMiddleware which is used in /signaling/samples/upvapi/index.html and /signaling/samples/basic/index.html sample pages.

To add model role configuration, you need to edit the shared settings .json file and add ‘ModelRoleConfig’ section under ‘StreamingConfig’ section.

Example configuration

"ModelRoleConfig": {
  "AllowUsageWhenNotSpecified": false,
  "AllowUsageWhenUserHasNoRole": false,
  "ModelRoles": [
    {
      "ModelUri": "file:///C:/MyModels/*",
      "Roles": [
        "ExampleRoleA"
      ]
    },
    {
      "ModelUri": "https://demo.universalplantviewer.com/*",
      "Roles": [
        "ExampleRoleC"
      ]
    }
  ],
  "RoleRestrictions": {
    "DefaultAllowedInstances": 5,
    "Restrictions": [
      {
        "Role": "ExampleRoleA",
        "MaxAllowedInstances": 10
      },
      {
        "Role": "ExampleRoleB",
        "MaxAllowedInstances": 8
      }
    ]
  }
}
Role Loading scenario (**)
ExampleRoleA Can only load maximum 10 instances of models under “file:///C:/MyModels/” folder.
ExampleRoleB Can only load maximum 5 instances(default setting), but currently has no access to any models.
ExampleRoleC Can only load maximum 8 instances of models under “https://demo.universalplantviewer.com/” domain.

Settings

Setting Description
AllowUsageWhenNotSpecified (boolean) Allows user to access to a model which is not defined inside the “ModelRoles” configuration.
AllowUsageWhenUserHasNoRole boolean) Allows user to access the models if user has no roles assigned. Be aware if set to true user(with no roles assigned) will access all models!
ModelRoles (list) User role rules per model uri.
ModelRoles/ModelUri (string) Upv model uri. Either in http or file scheme. In the example above with “” special character, user ExampleRoleA user has access to all models under ”C:/MyModels/” folder. And ExampleRoleC user has access to all models under ”https://demo.universalplantviewer.com/” domain. Moreover only ” ” special character can be used to give access to all models.
ModelRoles/Roles (list)User roles that have access to this model uri. “*” special character can be used to give access to all roles.
RoleRestrictions User restrictions per user role.
/DefaultAllowedInstances (int) Default allowed upv instance count that the user can load. When no restriction list or user role defined(under “Restrictions” list) this value will be used. By default this value is -1 which is unlimited.
RoleRestrictions/Restrictions (list) Restrictions settings list per user role.
/Role (string) User role.
/MaxAllowedInstances (int) Maximum allowed upv instances that this role can load.

(*) If a user has two roles, and ‘MaxAllowedInstances’ is defined for both roles, the highest value will be used.

(**) Models are provided from Watchdog.

Advanced Configuration Topics

ICE / STUN / TURN

ICE (Interactive Connectivity Establishment) deals with the problem of establishing a connection between two computers in the most direct and efficient way.

STUN (Session Traversal Utilities for NAT) is the the preferred way in handshaking process during initiating a connection because it makes the two peers communicating directly. But there are some situations like access from mobile networks, symmetric NAT or restrictive firewalls when this does not work out. In these cases a TURN server is needed (TURN: Traversal Using Relays around NAT). It acts as mediator relaying data in both directions between the peers.

Coturn Configuration Basics

A dedicated TURN server is recommended for productive environments. Therefore you need a server that is reachable for all clients (and UPVs) and a software like coturn which open source s. GitHub. We recommend to run it on separate server but not on the UPV Web Service machine

The configuration file under /etc/turnserver.conf needs some parameters to be uncommented or changed. A sample config file
can be found under config-sample/turnserver.conf

The changes for the running configuration include:

fingerprint  
lt-cred-mech  
user=turn1:mySecretPassword  
realm=realm  
syslog  
cli-password=mySecretCliPassword  

coturn allows multiple user entries to be configured e.g.:

user=user1:pw1  
user=user2:pw2  

To reduce the default range of used UDP ports [49152; 65535] edit:

min-port=55000
max-port=55050

Detailed coturn Installation

Requirements
  • Dual core CPU
  • 4GB RAM
  • Linux (tested on Debian) with ssh access
Install Webmin (Optional)
  • Open the file in your preferred editor. Here, we’ll use nano:
    sudo nano /etc/apt/sources.lis sudo nano /etc/apt/sources.list
  • Then add this line to the bottom of the file to add the new repository:
    deb http://download.webmin.com/download/repository sarge contrib
  • update packagelist
    sudo apt update
  • Then install gnupg1:
    sudo apt install gnupg1
  • Following that, download the Webmin PGP key with wget:
    wget http://www.webmin.com/jcameron-key.asc
  • Then add the package key:
    sudo apt-key add jcameron-key.asc
  • Next, update the list of packages again in order to include the now-trusted Webmin repository:
    sudo apt update
  • Update the system to the newest version
    sudo apt upgrade
  • Then install Webmin:
    sudo apt install webmin
  • Once the installation finishes, you’ll be presented with the following output:
    Webmin install complete. You can now login to
    https://your_server:10000 as root with your
    root password, or as any user who can use sudo.
Install UFW Firewall
sudo apt install ufw  
add allow ports to allow incoming connections  
sudo ufw allow <Port>  
example:  
sudo ufw allow 22  
Port 22 for ssh  
Port 80 for https  
Port 443 for stun\turn  
Port 3478 for stun\turn  
Port 10000 Optional if you use webmin  
Port 49152-65535 /udp for webrtc connections  

To enable the firewall

sudo ufw enable
Install coturn
sudo apt install coturn

To enable auto-start at boot time uncomment the following line in /etc/default/coturn:

TURNSERVER_ENABLED=1

Enable turnserver binding port < 1024:

sudo sed -i -e 18i"AmbientCapabilities=CAP_NET_BIND_SERVICE" /lib/systemd/system/coturn.service  
sudo systemctl daemon-reload
Install apache
Sudo apt install apache2

Visit http://my-host.com to see if it is working (“The Debian default Page” should show up).

Install certbot:
Sudo apt install certbot
Sudo apt install python3-certbot-apache
sudo certbot certonly --apache --deploy-hook "systemctl restart coturn && systemctl restart webmin" -d <your Domain>

Setup SSL Certificat webmin:

Go in the web interface >webmin>webmin Configuration>SSL Encryption

Private key file: /etc/letsencrypt/live/<your Domain>/privkey.pem  
Certificate file | seperate file: /etc/letsencrypt/live/<your Domain>/cert.pem  
Additional certificate files: /etc/letsencrypt/live/<your Domain>/chain.pem  
Save and go back and restart webmin

Setup SSL Certificat coturn in /etc/turnserver.conf

cert=/usr/local/etc/cert/cert.pem
pkey=/usr/local/etc/cert/privkey.pem

It´s needed to start the process with root rights to read the Certificate, after that the Process ist switch to the user from /etc/turnserver.conf

sed -i 's/User=turnserver/User=root/g' /lib/systemd/system/coturn.service
sed -i 's/Group=turnserver/Group=root/g' /lib/systemd/system/coturn.service
systemctl daemon-reload
systemctl restart coturn
Configuration Turnserver

The configuration file under /etc/turnserver.conf needs some parameters to be uncommented or changed. In the config file are all parameters explained Example turnserver.conf:

To edit the /etc/turnserver.conf you can edit with nano:

Sudo nano /etc/turnserver.conf

The following settings are necessary:

  • listening-port
  • tls-listening-port
  • external-ip
  • listening-ip
  • min-port
  • max-port
  • user and password or use database
  • realm
  • cert
  • pkey
  • fingerprint
  • lt-cred-mech
  • proc-user
  • proc-group
  • nocli (optional)

After config changes restart the service (systemctl restart coturn).

Ensure that the firewall allows TCP and UDP traffic for listening-port, tls-listening-port (defaults 3478, 5349 or 443) and the UDP port range between min-port and max-port (default 49152 - 65535).

Using A Reverse Proxy

Appache Reverse Proxy Configuration

Requirement Linux with working apache “http” or “https”! This installation is with https on a Debian system. To set up Apache as a reverse proxy server you will need to enable mod_proxy. Some other common mods you may need are below. - mod_proxy - mod_http - mod_headers - mod_html - mod_proxy_http - mod_proxy_wstunnel - mod_rewrite To enable mods in Ubuntu/ Debian you need to make sure they are installed, then enabled. For example, installing and enabling mod_proxy would look like this:

apt-get install libapache2-mod-proxy-html a2enmod mod_proxy

Once these mods are enabled, we can begin editing the Apache config. The locations of these vary depending on your Linux distribution. For RHEL based distributions, this will be your httpd.conf; for Debian based, sites-available/default. Inside your VirtualHost tag create a Location tag which matches the external path you wish to use. For this example we will use /.

<Location /upvweb>
    # commands go here
</Location>

Inside the Location tag add the proxy options ProxyPass and ProxyPassReverse followed by the site address which will be the target of the proxy. To make WebSocket protocol working a URL rewrite rule is needed. Depending on whether SSL is used or not, the rewrite expression starts either with wss:// or with ws://.You will also need a couple of lines to allow access.

<VirtualHost *:443>
  RewriteEngine on
  RequestHeader set "X-Forwarded-Proto" "https"
  <Location /ids>
    ProxyPass https://localhost:44358
    ProxyPassReverse https://localhost:44358
  </Location>
  <Location /upvweb>
    ProxyPass https://mywebupv.com:3000
    ProxyPassReverse https://mywebupv.com:3000
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule /sighub/(.*) wss://mywebupv.com:3000/sighub/$1 [P]
  </Location>
  TimeOut 60
  ServerName mywebupv.com
  ErrorLog "/var/log/apache2/mylocal-https-error_log"
  SSLCertificateFile "/etc/apache2/ssl/mylocal.crt"
  SSLCertificateKeyFile "/etc/apache2/ssl/mylocal.key"
  SSLEngine on
  SSLProxyEngine on
  SSLVerifyClient optional
</VirtualHost>

Restart apache or reload the settings for the changes to take effect:

systemctl restart apache2

Now all requests sent to https://mywebupv.com/upvweb will be forwarded to https://mywebupv.com:3000 thus port 3000 can be blocked for outgoing traffic.

Example Apache reverse proxy VirtualHost:

The example shows an Apache VirtualHost which is listening on port 443. The configuration accepts requests on which match the mywebupv.com/upvweb hostname and forwards the requests to the backend server https://mywebupv.com:3000. Identity Server instance is configured to run on port 44358 and is reachable via proxy at https://mywebupv.com/idsupv.

If you are switching protocols you need to add the following header in your Location or VirtualHost section: RequestHeader set “X-Forwarded-Proto” “http”.

The header setting for “Content-Security-Policy“ is needed internally for communication between WebUPV and Identity Server to allow token updates silently.  

sharedsettings.json For Reverse Proxy

In upvweb‘s sharedsettings.json leave the SignalingUrl as without proxy e.g. pointing to https://mywebupv.com:3000/signaling. The key IdentityServerUrl must contain the forwarded address e.g “IdentityServerUrl”: “https://mywebupv.com/idsupv” Identity Server (idsupv) needs the following configuration in sharedsettigns.json: “IdentityServerUrl”: “https://mywebupv.com:44358”, “IdentityServerProxyUrl”: “https://mywebupv.com/idsupv”,

To make ensure that idsupv works with upvweb both with technical URL and proxy URL, it is recommended to add both URLs to the SignalingUrl key, so your StreamingConfig section looks like:

"StreamingConfig": {
  "SignalingServerUrl": ["https://mywebupv.com/webupv/signaling",
      "https://mywebupv.com:3000/signaling"],
  "SignalingApiCredential": "myapipassword"
}

nginx

Most things related to UpvWebServices from the Apache section above apply to nginx as reverse proxy too. A sample nginx.conf but for port 80 without SSL looks like:

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    keepalive_timeout  65;
    map $http_upgrade $connection_upgrade {
        default Upgrade;
        ''      close;
    }
    server {
        # set port where proxy is listening to clients, in most case 80 for HTTP or 443 for HTTPS
        listen       80;
        # your server name
        server_name  sig.local;

        # path appended to server_name where to find WebUPV  from the public
        location /upvweb/ {
            # Host name from UpvWebServicesUrl combined with UpvWebServicesPort as specified in sharedsetting.json
            proxy_pass         http://mywebupv.com:3000/;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   X-Forwarded-Host  $host;

        }
        # path appended to server_name where to find Identity Server
        location /upvids/ {
            # Host name from IdentityServerUrl combined with IdentityServerPort as specified in sharedsetting.json
            proxy_pass         http://mywebupv.com:44358/;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
            proxy_set_header   X-Forwarded-Host  $host;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    include servers/*;
}

Troubleshooting

UPV For Render Streaming

  • Local firewall or anti virus software is blocking ports.
  • SignalingApiCredential in defaultConfig.upv does not match the one in UPV Web Services’ sharedsettings.json.
  • Wrong SignalingUrl in defaultConfig.upv (needs to end with /signaling).
  • No connection available due to strictly configured network:
    use a TURN server to enable relay connections.

Coturn

  • Service or binary not restarted after config changes.
  • Port locked by another service or not available (look especially 443 when running apache in parallel).
  • Port blocked by firewall.
  • User or password wrong.
  • Permissions not granted to dedicated user.
  • Wrong path to certificate or key file.