#############
Machine Setup
#############

This guide describes how to configure your server to be able to run the HOOPS Server to support both client-side rendering (CSR) and server-side rendering (SSR) modes. The machine provisioning requirements depend on whether you are supporting CSR or SSR rendering. The primary difference between the two rendering modes is that in order to support SSR, the server requires a graphics card attached with proper drivers.


Windows-specific
================

Setting up a Windows server
---------------------------

For CSR applications the HOOPS Communicator Installer will ensure that all required code redistributables are in place on the target system. Using the installer is the preferred method for getting HOOPS Communicator.

For SSR applications, it is essential to have 3D acceleration enabled on your server. HOOPS Communicator recommends using NVIDIA hardware. You will need to ensure that you have an up to date graphics card driver installed and that 3D hardware-acceleration is activated. The steps required to achieve this vary depending on your specific environment.


Configuring multiple Windows GPUs
---------------------------------

On Windows, HOOPS Communicator can leverage multiple installed GPUs with NVIDIA hardware only. In order to use this feature, your system wil require workstation class cards Quadro or Tesla. To take advantage of multiple GPUs you will need to set the ssrGpuCount configuration value in your :doc:`server configuration file </prog_guide/servers/hoops_server/configuration>` to the number of GPUs present in your system. If your system contains graphcs cards with more than one GPU, this number will be greater than the number of installed graphics cards.


Linux-specific
==============

Setting up a Linux server
-------------------------

If your Linux box has a desktop windowing system, you can use the HOOPS Communicator Installer to download and extract HOOPS Communicator. Otherwise you will need to download the HOOPS Communicator package from the developer zone and inflate it manually. For CSR rendering, no additional machine setup is required.

For SSR applications, you will need to install both the X-server and an NVIDIA graphics driver. For SSR to function correctly, the X-server must be running. For additional information on setting up X and the NVIDIA driver, refer to the :doc:`Supported Platforms page </overview/supported-platforms>`.


Configuring multiple Linux GPUs
-------------------------------

On Linux, HOOPS Communicator can leverage multiple installed GPUs with NVIDIA hardware only. In order to leverage this feature, you will need to generate an appropriate X configuration file using the command: ``nvidia-xconfig --enable-all-gpus --allow-empty-initial-configuration``.


The following is a sample X configuration file generated on an AWS g2.8xlarge instance with 4 GPUs::

	# nvidia-xconfig: X configuration file generated by nvidia-xconfig
	# nvidia-xconfig:  version 370.28  (buildmeister@swio-display-x64-rhel04-17)  Thu Sep  1 20:22:52 PDT 2016
	Section "ServerLayout"
		Identifier     "Layout0"
		Screen      0  "Screen0"
		Screen      1  "Screen1" RightOf "Screen0"
		Screen      2  "Screen2" RightOf "Screen1"
		Screen      3  "Screen3" RightOf "Screen2"
		InputDevice    "Keyboard0" "CoreKeyboard"
		InputDevice    "Mouse0" "CorePointer"
	EndSection
	Section "Files"
	EndSection
	Section "InputDevice"
		# generated from default
		Identifier     "Mouse0"
		Driver         "mouse"
		Option         "Protocol" "auto"
		Option         "Device" "/dev/psaux"
		Option         "Emulate3Buttons" "no"
		Option         "ZAxisMapping" "4 5"
	EndSection
	Section "InputDevice"
		# generated from default
		Identifier     "Keyboard0"
		Driver         "kbd"
	EndSection
	Section "Monitor"
		Identifier     "Monitor0"
		VendorName     "Unknown"
		ModelName      "Unknown"
		HorizSync       28.0 - 33.0
		VertRefresh     43.0 - 72.0
		Option         "DPMS"
	EndSection
	Section "Monitor"
		Identifier     "Monitor1"
		VendorName     "Unknown"
		ModelName      "Unknown"
		HorizSync       28.0 - 33.0
		VertRefresh     43.0 - 72.0
		Option         "DPMS"
	EndSection
	Section "Monitor"
		Identifier     "Monitor2"
		VendorName     "Unknown"
		ModelName      "Unknown"
		HorizSync       28.0 - 33.0
		VertRefresh     43.0 - 72.0
		Option         "DPMS"
	EndSection
	Section "Monitor"
		Identifier     "Monitor3"
		VendorName     "Unknown"
		ModelName      "Unknown"
		HorizSync       28.0 - 33.0
		VertRefresh     43.0 - 72.0
		Option         "DPMS"
	EndSection
	Section "Device"
		Identifier     "Device0"
		Driver         "nvidia"
		VendorName     "NVIDIA Corporation"
		BoardName      "GRID K520"
		BusID          "PCI:0:3:0"
	EndSection
	Section "Device"
		Identifier     "Device1"
		Driver         "nvidia"
		VendorName     "NVIDIA Corporation"
		BoardName      "GRID K520"
		BusID          "PCI:0:4:0"
	EndSection
	Section "Device"
		Identifier     "Device2"
		Driver         "nvidia"
		VendorName     "NVIDIA Corporation"
		BoardName      "GRID K520"
		BusID          "PCI:0:5:0"
	EndSection
	Section "Device"
		Identifier     "Device3"
		Driver         "nvidia"
		VendorName     "NVIDIA Corporation"
		BoardName      "GRID K520"
		BusID          "PCI:0:6:0"
	EndSection
	Section "Screen"
		Identifier     "Screen0"
		Device         "Device0"
		Monitor        "Monitor0"
		DefaultDepth    24
		Option         "AllowEmptyInitialConfiguration" "True"
		SubSection     "Display"
			Depth       24
		EndSubSection
	EndSection
	Section "Screen"
		Identifier     "Screen1"
		Device         "Device1"
		Monitor        "Monitor1"
		DefaultDepth    24
		Option         "AllowEmptyInitialConfiguration" "True"
		SubSection     "Display"
			Depth       24
		EndSubSection
	EndSection
	Section "Screen"
		Identifier     "Screen2"
		Device         "Device2"
		Monitor        "Monitor2"
		DefaultDepth    24
		Option         "AllowEmptyInitialConfiguration" "True"
		SubSection     "Display"
			Depth       24
		EndSubSection
	EndSection
	Section "Screen"
		Identifier     "Screen3"
		Device         "Device3"
		Monitor        "Monitor3"
		DefaultDepth    24
		Option         "AllowEmptyInitialConfiguration" "True"
		SubSection     "Display"
			Depth       24
		EndSubSection
	EndSection


Network configuration
=====================

Default ports
-------------

By default, the HOOPS Server makes use of the following ports. If you are not using a proxy, you will need to ensure they are open in your firewall and security settings.

.. csv-table::

	"File server", "11180"
	"Spawning service", "11182"
	
	
.. _reverse-proxy:
	
Reverse proxy
-------------

Keep in mind that each Communicator streaming session uses its own unique port. It is recommended to use a reverse proxy on your HOOPS Server in order to limit the ports that need to be exposed to the outside world. There are multiple ways to accomplish this.

The HOOPS Server comes built in with the ability to proxy connections. This functionality is provided by `node-http-proxy <https://github.com/http-party/node-http-proxy>`_ package. In this case you will only need to ensure that the port to your spawning service is reachable from the outside world. When creating viewers, point the :ref:`endpointUri <api_ref/viewing/interfaces/Communicator.WebViewerConfig:endpointuri>` option of your :doc:`WebViewerConfig </api_ref/viewing/interfaces/communicator.webviewerconfig>` object to the Spawning Service, and it will proxy websocket connections for you.

.. literalinclude:: /../../applications/client/docs/PG_Server_MachineSetup.ts
	   :start-after: //! [server_with_proxy]
	   :end-before: //! [server_with_proxy]

Nginx can also be used to proxy websocket connections by defining a rule in the config file. This solution works for all platforms. The sample below shows how to perform websocket proxying using a rewrite rule. In this case the port that nginx will proxy to is encoded in the URL itself. To use this scheme, set your :ref:`endpointUri <api_ref/viewing/interfaces/Communicator.WebViewerConfig:endpointuri>` to a value such as:

*view.communicator.com/wsproxy/11000*


Reverse proxy server configuration
----------------------------------

.. code-block:: 

	#nginx.conf file. Non-essential settings have been omitted.
	http {
	  server {
		#For this example, NGINX will listen on port 443 (default HTTPS port).
		listen 443; 
		
		#SSL Related Settings
		ssl on;
		ssl_certificate    /path/to/your/cert.crt;
		ssl_certificate_key    /path/to/your/private_key.key;
		
		#This rule handles HTTP requests with the 'httpproxy' path prefix.
		location /httpproxy/ {
			#Rewrite request URI (path), capturing some info in the process. 
			#Capture 1 = back-end server port. Capture 2 = back-end server path.
			rewrite /httpproxy/([^/]+)/([^/]+) /$2 break; 

			#Proxy to the back end server
			proxy_pass http://127.0.0.1:$1; 			
		}
		
		#This rule handles HTTPS requests with the 'wsproxy' path prefix.
		location /wsproxy/ {
			#Rewrite request URI (path), capturing some info in the process. 
			#Capture 1 = back-end server port.
			rewrite /wsproxy/([^/]+) / break;
							
			#Proxy to the back-end server, passing the WebSockets upgrade through.
			proxy_pass http://127.0.0.1:$1;
			proxy_http_version 1.1;
			proxy_set_header Upgrade $http_upgrade;
			proxy_set_header Connection "upgrade";
		}
	  }
	}
