Проект

Общее

Профиль

Удалённый запуск приложений 3D через VirtualGL

В данной статье игра StarCraft II приведена в качестве примера, т.к. здесь мы разбираем, в том числе, передачу звука без задержек.
Добавил(а) Кальметов Игорь около 3 лет назад

Удалённый запуск приложений 3D через VirtualGL (или StreamGaming собственными руками)

Мы будем играть в StarCraft II на обычном офисном ноутбуке (ни серьёзной видеокарты, ни мощного процессора).
Имеем:

  • Сетевое оборудование: обычный домашний роутер с WiFi
  • Средний домашний компьютер (сервер):
    • Процессор: Intel(R) Core(TM) i5-2400 CPU @ 3.10GHz (4 ядра/4 потока)
    • Оп. память: 8 GB DDR3
    • Видеокарта: AMD Radeon RX550 2GB
    • ОС: Linux
    • Сеть: 1Gbps Ethernet (проводом в роутер)
  • Офисный ноутбук (клиент):
    • Процессор: Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz (2 ядра/4 потока)
    • Видеокарта: Intel(R) HD Graphics 4400 (интегрированная)
    • ОС: Linux
    • Сеть: WiFi

Подготовка сервера

Установка и настройка VirtualGL

На компьютере устанавливаем сервер SSH, если этого не было сделано ранее.
Устанавливаем драйвер для видеоадаптера, если это необходимо. Для NVIDIA необходимо установить проприетарный драйвер. Для AMD, скорее всего подойдёт имеющийся открытый.
В нашем случае мы используем открытый драйвер AMDGPU.
Устанавливаем VirtualGL из пакета для своего дистрибутива. Для дистрибутивов на базе Debian есть пакет в разделе загрузок официального сайта.
Для Gentoo Linux ebuild есть в официальном дереве portage.
Если на сервере стоит 64-битный Linux (что очень рекомендовано), то неообходимо установить VirtualGL и 64-битный, и 32-битный. Это нужно для запуска, в том числе, 32-битных 3D приложений (которыми являются многие игры Windows).
После установки запускаем скрипт конфигурации от пользователя root:

vglserver_config

Соглашаемся с параметрами по умолчанию.
Добавляем основного пользователя (например, ivanov) в группу vglusers:

usermod -a -G vglusers ivanov

Настройка перенаправления звука.

В сети множество инструкций и рекомендаций с использованием сетевого режима pulseaudio, поточное вещание звука с псевдоаудиокарты через ffmpeg и т.д.
Сетевой режим PulseAudio хорош ровно до тех пор, пока у нас стабильное проводное соединение от клиента до сервера. Поточное вещание через ffmpeg имеет задержку, хоть и небольшую, но существенную, когда речь идёт о приложениях (например, играх), которые завязаны на восприятие звука.
Нам поможет roc-toolkit. Задержки с данным решением очень незначительны.
Для начала включим псевдоаудиокарты (в нашем случае 5 штук):

  • создаём файл /etc/modprobe.d/snd-aloop.conf следующего содержимого:
    options snd-aloop enable=1,1,1,1,1 index=10,11,12,13,14 id=Loopback0,Loopback1,Loopback2,Loopback3,Loopback4
    
  • добавляем в файл /etc/modules-load.d/modules.conf имя модуля:
    snd-aloop
    

    Несколько штук нам нужно для возможности одновременного запуска игр с разных клиентов.
  • либо подключаем модуль руками:
    modprobe snd-aloop
    

    , либо перезагружаем сервер.

Сборка roc достаточно проста и описана на оф.сайте. Установку после сборки (этап install) мы делать не будем.
На сервере в домашнем каталоге основного пользователя (которого мы добавляли в группу vglusers) создаём каталог

.local/bin

В него копируем собранный roc-send (убеждаемся, что он исполняемый).

Подготовка клиента

Установка VirtualGL

Устанавливаем VirtualGL из пакета для своего дистрибутива. Для дистрибутивов на базе Debian есть пакет в разделе загрузок официального сайта.
Для Gentoo Linux ebuild есть в официальном дереве portage.
Для Windows установщик есть там же.

Сборка roc-toolkit для приёма звукового потока

Собираем roc так же, как и на сервере, но копируем в папку ~/.local/bin на ноутбуке roc-recv.

Настройка подключения к серверу без пароля.

На каждом клиентском ноутбуке создадим ключ SSH:

ssh-keygen

На запросе пароля просто жмём Enter (т.е. пароль пустой).
После этого с каждого ноутбука устанавливаем открытую чать ключа на сервер:

ssh-copy-id ivanov@server_hostname_or_ip

На запросе пароля вводим пароль основного пользователя сервера ivanov.
Всё, теперь мы можем входить на сервер по SSH без пароля.

Установка и настройка игры

В рамках этой статьи мы будем играть в StarCraft II. Данное приложение есть только для ОС Windows и MacOS. Под Linux мы будем запускать StartCraft через wine.
В нашем случае мы обеспечили возможность перенаправления звука для пяти клиентов (хотя больше двух на этой конфигурации сервера не проверялось).
Для каждого пользователя необходимо будет создать свой корень wine. Устанавливать StarCraft мы будем только в один корень, а потом просто создадим копии этого корня для второго пользователя и следующих.

Для начала подключимся с ноутбука к серверу с VirtualGL:

vglconnect ivanov@server_hostname_or_ip

Далее указываем рабочий корень wine:
export WINEPREFIX="/home/ivanov/.wine_sc2_1" 

и запускаем конфигуратор winecfg для создания и настройки корня.
Окно конфигуратора отобразится на ноутбуке. Во вкладке Вид и интеграция необходимо указать для папки Мои документы путь до отдельной своей папки.
Т.к. в папку Мои документы игра сохраняет данные учётной записи и свои настройки, то для каждого корня (и пользователя) эта папка должна быть отдельной.
Закрываем конфигуратор и запускаем установку StarCraft:
wine путь/до/установщика/игры/Setup.exe

На ноутбуке должно появиться окно установщика. Следуем указаниям.
После установки копируем папку с корнем для второго пользователя:
cp -a .wine_sc2_1 .wine_sc2_2

Если предполагаются ещё пользователи, создаём для них копию корня.

Настройка вывода звука wine

Для каждого корня StarCraft необходимо настроить вывод на отдельную псевдоаудиокарту. Экспортируя WINEPREFIX для каждого корня, запускаем конфигуратор winecfg и во вкладке Аудио выбираем устройство вывода. Для удобства мы указали в параметрах модуля snd-loop псевдонимы карт, как Loopback0, Loopback1,...
В конфигураторе winecfg будет по 2 строки для каждого псевдонима. Loopback0 будет просто "Out: Loopback", Loopback1 - "Out: 11-Loopback" и т.д.
Соответственно для первого пользователя надо выбрать один из двух вариантов Loopback, для второго - 11-Loopback, для третьего - 12-Loopback и т.д.

Определение точного варианта устройства вывода из двух

Для определения, какое же устройство из двух выбрать, можно воспользоваться, например, mplayer для windows.
Подключаемся в отдельном терминале к серверу через SSH:

ssh ivanov@server_hostname_or_ip

Запускаем транслятор звукового потока, подключая его к 0-ой псевдоаудиокарте:
/home/ivanov/.local/bin/roc-send -s rtp+rs8m:192.168.1.101:10001 -r rs8m:192.168.1.101:10002 --rate 22050 -d alsa -i hw:Loopback0,1,0

192.168.1.101 - адрес IP ноутбука, с которого сейчас подключены к серверу. Т.е. транслятор будет слать звук на наш ноутбук.
В третьем терминале на ноутбуке запускаем приёмник звукового потока:
~/.local/bin/roc-recv -s rtp+rs8m::10001 -r rs8m::10002

В первом терминале (где мы запускали winecfg на сервере) экспортируем WINEPREFIX для первого корня и запускаем winecfg.
Выбираем один из вариантов "Out: Loopback". Закрываем winecfg и запускаем воспроизведение звука через mplayer.exe:
wine mplayer.exe /usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga

На воспроизведение можно указать любой звуковой файл. Здесь мы используем один из системных.
Если услышали на ноутбуке звук (в данном случае - пищание будильника), то устройство вывода выбрано верно. Если нет, запускаем winecfg, выбираем второй варинат "Out: Loopback", закрываем и повторяем запуск mplayer.exe.
После успешного указания устройства завершаем работу транслятора и приёмника звука. Для остальных пользователей проделываем то же самое, но экспортируем WINEPREFIX для следующего корня (home/ivanov/.wine_sc2_2), транслятор вешаем на следующую псевдоаудиокарту (hw:Loopback1,1,0), а в winecfg выбираем один из двух варинатов "Out: 11-Loopback".

Скрипты запуска игры

Сервер

На сервере в папке /home/ivanov/.local/bin создаём скрипт запуска игры vgl_sc2_1.sh следующего содержания:

#!/bin/bash
export WINEPREFIX="/home/ivanov/.wine_sc2_1" 
export LANG=ru_RU.UTF-8
###
C_IP=$(echo $SSH_CLIENT | cut -f2 -d'=' | cut -f1 -d' ')
/home/ivanov/.local/bin/roc-send -s rtp+rs8m:$C_IP:10001 -r rs8m:$C_IP:10002 --rate 22050 -d alsa -i hw:Loopback0,1,0 &
ROC_PID=$(echo $!)
###
cd $WINEPREFIX/drive_c/Program\ Files\ \(x86\)/StarCraft\ II/
wine 'StarCraft II.exe'
while ps -A | grep \\.exe\\b 2>/dev/null 1>/dev/null
do
    sleep 1
done
kill $ROC_PID
sleep 1

Делаем его исполняемым.
Здесь важно понимать, что:

  • дискретизация звука 22050 выбрана для уменьшения требуемой полосы пропускания сети для звукового потока.
  • vgl_sc2_1.sh - скрипт для первого пользователя. Для следующих надо создавать копии этого скрипта с соответствующим именем (vgl_sc2_2.sh, vgl_sc2_3.sh,...).
  • /home/ivanov/.wine_sc2_1 - корень wine для первого пользователя. Для следующих пользователей надо в их скриптах указывать их корни.

Клиент

На ноутбуке в папке ~/.local/bin создаём скрипт удалённого запуска remote_sc2.sh следующего содержания:

#!/bin/bash
~/.local/bin/roc-recv -s rtp+rs8m::10001 -r rs8m::10002 &
ROC_PID=$(echo $!)
vglconnect ivanov@server_hostname_or_ip vglrun -q 30 -sample 4x /home/ivanov/.local/bin/vgl_sc2_1.sh
kill $ROC_PID

Делаем его исполняемым.
Здесь /home/ivanov/.local/bin/vgl_sc2_1.sh - путь до скрипта запуска игры первого пользователя на сервере. Для остальных пользователей на их ноутбуках надо указывать путь до их скриптов запуска.
Параметры
-q 30 -sample 4x

уменьшают качество передаваемой картинки с сервера, тем самым уменьшая требуемую полосу пропускания сети. Это нужно, если ноутбук подключается к домашней сети по WiFi.
Если же организовано высокоскоростное проводное сеодинение, то эти параметры можно убрать.
Для теста можно запустить ~/.local/bin/remote_sc2.sh из терминала, но желательно создать кнопку запуска (файл .desktop).

Заключение

В данной статье игра StarCraft II приведена в качестве примера, т.к. здесь мы разбираем, в том числе, передачу звука без задержек.
В качестве удалённого приложения может быть любое приложение, требующее аппаратную поддержку OpenGL (например, 3D моделирование, 3D проектирование...).
На указанном стенде были запущены одновременно два экземпляра игры StarCraft II с двух разных слабых ноутбуков, подключённых к домашней сети по WiFi.
Была проведена полноценная игровая сессия в несколько боёв группой из двух игроков.
На средних настройках графики игры частота кадров в секунду (FPS) не падала ниже 50. Качество картинки вполне приемлемое. Задержки звука если и присутствовали, то человеческим ухом не улавливались.

VirtualGL незаслуженно выпал из освещения нашей IT медиасферой. Возможности, которые даёт эта технология, очень любопытны.


Комментарии