Dedicated vs Listen Server.Replication.Remote Procedure Calls.

Список разделов:
1.Введение
2.Framework & Network in Unreal Engine 4.
3.Dedicated vs Listen Server.Replication.Remote Procedure Calls. Вы здесь
4.Ownership.Actor:Role,RemoteRole,Relevancy,Priority.Traveling in Multiplayer.
5.Online Subsystem Overview.How to Start a Multiplayer Game.

Dedicated vs Listen Server
Dedicated Server

Выделенный сервер представляет собой автономный сервер, который не требует клиента.
Он работает отдельно от клиента игры и в основном используется, чтобы под управлением сервера, игроки всегда могли присоединиться/уйти.
Выделенные серверы могут быть скомпилированы для Windows и Linux, и могут быть запущены на виртуальных серверах, на которые игроки могут подключаться через фиксированный IP-адрес.
Выделенные серверы не имеют визуальной части, поэтому они не нуждаются в пользовательский интерфейс, и они не имеют PlayerController. Они также не имеют персонажей или подобного представляющего их в игре.

Listen-Server
Listen-Server представляет собой сервер, который также является клиентом.
Это означает, что сервер всегда имеет по крайней мере один подключенный клиент.
Этот клиент называется Listen-Server, и если он отсоединится, сервер будет выключен.
Благодаря тому, что он также является клиентом, Listen-Server нуждается в пользовательском интерфейсе и имеет PlayerController, который представляет собой часть клиента. Получение «PlayerController (0)» на Listen-сервер, вернет PlayerController того самого Клиента.
Поскольку Listen-сервер работает на самом клиенте, то IP, который нужен другим для подклюения к нему,будет одним из клиентов. По сравнению с выделенным сервером, это часто приходит с проблемой интернет-пользователей, не имеющих статического IP-адресса.
Но с помощью OnlineSubsystem (поясняеться дальше), проблема меняющихся IP может быть решена.
Replication
Что такое Репликация?
Репликация является действием передачи сервером информации/данных для клиентов.
Это может быть ограничено конкретными субъектами и группами. Блупринты в основном выполняют репликацию в соответствии с настройками затронутого AActor.
Первый класс, который способен реплицироваться свойствами, является актер.
Все ранее упомянутые классы наследуются от эктора в какой-то момент, что дает им возможность реплицировать свойства, если это необходимо.
Хотя не все из них делают это таким же образом.
GameMode, например, не поддерживает репликацию всего, и существует только на сервере.
Как использовать Репликацию?
Репликацию можно активировать в Class Defaults/Constructor в дочернем экторе:
UE4_Network_Compendium_by_Cedric_eXi_Neukirchenjpg_Page50_Image1

ATestCharacter::ATestCharacter() {
// Network game, so let’s setup Replication
bReplicates = true;
bReplicateMovement = true;
}

Эктор с «bReplicates» установленным в TRUE будет спавниться и реплицироваться на всех клиентах когда заспавнится сервером.
Если клиент спавнит этот эктор, то эктор будет существовать только на этом самом клиенте.

Replicating Properties
Таким образом, когда репликация включена, мы можем повторить переменные. Есть несколько способов сделать это. Мы начнем с самого основного:
111 Установка выпадающего меню «Replication» на «Replicated» будет убеждаться, что это переменная получает реплицирование на всех реплицированных инстансах этого эктора. Конечно, это работает только для актеров, которые установлены для репликации.
111 Реплицированные переменные помечены двумя белыми кружками.

Репликация переменной в C ++ требует немного больше работы в начале.
Но это также позволяет нам определить, кто мы хотим реплицировать эту переменную.

/* Header file inside of the Classes declaration */
// Create replicated health variable
UPROPERTY(Replicated)
float Health;

Файл .cpp получит эту функцию «GetLifetimeReplicatedProps«. Заголовок объявления этой функции, уже предусмотрен через некоторые UE4 макросы, так что у нас нет нужды заботиться об этом. Именно здесь вы определяете правила репликации переменной.

void ATestPlayerCharacter::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// Here we list the variables we want to replicate + a condition if wanted
DOREPLIFETIME(ATestPlayerCharacter, Health);
}

Вы также можете сделать условную репликацию здесь:
(Это не поддерживается в блупринтах)

// Replicates the Variable only to the Owner of this Object/Class
DOREPLIFETIME_CONDITION(ATestPlayerCharacter, Health, COND_OwnerOnly);
Условие Описание
COND_InitialOnly Это свойство будет пытаться отправить на исходную связку.
COND_OwnerOnly Это свойство будет отправить только владельцу эктора.
COND_SkipOwner Это свойство отправить каждое соединение, кроме владельца.
COND_SimulatedOnly Это свойство будет посылать только симулированным экторам.
COND_AutonomousOnly Это свойство будет посылать только автономным экторам.
COND_SimulatedOrPhysics Это свойство будет посылать только симулированным или bRepPhysics экторам.
COND_InitialOrOwner Это свойство будет посылать на исходную связку, или владельца актера.
COND_Custom Это свойство не имеет определенного состояния, но имеет возможность переключения вкл / выкл через SetCustomIsActiveOverride.

Очень важно, чтобы вы понимали, что весь процесс репликации работает только от сервера к клиенту, а не наоборот. Позже, мы узнаем, как реплицировать что-то на сервере, чем клиент хочет поделиться с другими (например: Playername).

Другим вариантом репликации является так называемая «RepNotify» версия.
Она использует функцию, которая будет вызываться во всех инстансах при получении обновленного значения.
При этом, вы можете вызвать логику, которая должна быть вызвана после того, как значение было реплицированно.

111 В блупринте эта функция будет создана автоматически после того, как вы выберите RepNotify из выпадающего меню Replication:

111

С++ версия потребует немного больше, но работает также:

/* Header file inside of the Classes declaration */
// Create RepNotify Health variable
UPROPERTY(ReplicatedUsing=OnRep_Health)
float Health;
// Create OnRep Function | UFUNCTION() Macro is important! | Doesn’t need to be virtual though
UFUNCTION()
virtual void OnRep_Health();

/* CPP file of the Class */
void ATestCharacter::OnRep_Health() {
if(Health < 0.0f)
PlayDeathAnimation();
}

С «ReplicatedUsing=FUNCTIONAME«, мы указываем функцию, которая должна получить вызов, когда переменная успешно реплицированна. Эта функция должна иметь макрос «UNFUNCTION ()«, даже если он пустой!

Remote Procedure Calls

Ещё одна форма репликация называется «RPC«.
Краткая форма для «удаленного вызова процедур».
Они используются для вызова чего-либо на другом инстансе. Ваш ТВ пульт делает то же самое с вашим телевизором.
UE4 использует его для вызова функции от клиента к серверу, сервера к клиенту или сервера к определенной группе.
Эти RPC не могут иметь возвращаемого значения! Для того, чтобы вернуть что-то, что вам нужно использовать второй RPC.
Но это работает только при соблюдении определенных правил.
Они перечислены в этой таблице, которую можно найти в официальной документации:
Run on Server — предназначен для выполнения на инстансе сервера эктора.
Run on owning Client — предназначен для выполнения на владельце этого эктора.
NetMulticast — предназначен для выполнения на всех инстансах этого эктора.

Требования и Предостережения

Ниже указаны несколько требований которые должны быть соблюдены для полного функционала RPC :

  1. Они должны вызыватся экторами.
  2. Эктор должен быть реплицирован.
  3. Если RPC вызывается с сервера для выполнения на клиенте, то только клиент который фактически владеет этим эктором будет выполнять эту функцию.
  4. Если RPC вызывается от клиента для выполнения на сервере, клиент должен владеть эктором, который вызывается в RPC.
  5. Multicast RPCs
      являются исключением:
  • Если они вызываются с сервера, сервер будет выполнять их локально, а также выполнять их на всех подключенных в данный момент клиентах.
  • Если они вызываются с клиентов, они будут выполнять только локально, и не будет выполняться на сервере.
  • Теперь, у нас есть простой механизм регулирования событий Multicast:
  • Функция Multicast не будет реплицирована более чем два раза на данном экторе в период обновления сети. В будующем, ожидается улучшение этого аспекта.

RPC вызывается с сервера

Владение эктором Не реплицировано Сетевой мультикаст Сервер Клиент
клиент владеет эктором Запускается на сервере Запускается на сервере и всех клиентах Запускается на сервере запускает на клиентах владеющих эктором
сервер владеет эктором Запускается на сервере Запускается на сервере и всех клиентах Запускается на сервере Запускается на сервере
ничейный эктор Запускается на сервере Запускается на сервере и всех клиентах Запускается на сервере Запускается на сервере

RPC вызывается с клиента

Владение эктором Не реплицировано Сетевой мультикаст Сервер Клиент
принадлежит вызывающему клиенту Запускается на вызывающем клиенте Запускается на вызывающем клиенте Запускается на сервере Запускается на вызывающем клиенте
владение разными клиентами Запускается на вызывающем клиенте Запускается на вызывающем клиенте Сброшено Запускается на вызывающем клиенте
сервер владеет эктором Запускается на вызывающем клиенте Запускается на вызывающем клиенте Сброшено Запускается на вызывающем клиенте
ничейный эктор Запускается на вызывающем клиенте Запускается на вызывающем клиенте Сброшено Запускается на вызывающем клиенте
RPCs в блупринтах

RPCs в блупринтах создаются путем создания CustomEvents и установления их в репликацию.
RPCs не может иметь возвращаемого значения! Таким образом, функции не могут быть использованы для их создания.

111 111

Флажок «Reliable» может быть использован для обозначения RPC как «важный», убедитесь, что он будет выполнен в 99,99% случаях, а не упадёт из-за проблем соединения или чего-то подобного.

Примечание: Не отмечайте каждый RPC, как надежный!
RPC в C++

Для того, чтобы использовать все сетевые фичи в C ++, вам нужно включить «UnrealNetwork.h» в заголовке проекта!
RPCs в C ++ относительно легко создабтся, нам нужно только добавить спецификатор к макросу UFUNCTION ().

// This is a Server RPC, marked as unreliable and WithValidation (is needed!)
UFUNCTION(Server, unreliable, WithValidation)
void Server_PlaceBomb();

СРР файл будет выполнять другую функцию. Поэтому нужно добавить суффикс ‘_Implementation‘.

// This is the actual implementation (Not Server_PlaceBomb). But when calling it, we use «Server_PlaceBomb»
void ATestPlayerCharacter::Server_PlaceBomb_Implementation() {
// BOOM!
}

CPP файл также нуждается в версии с «_Validate» в качестве суффикса. Подробнее об этом позже.

bool ATestPlayerCharacter::Server_PlaceBomb_Validate() {
return true;
}

2 других RPC типа создаются следующим образом:
Клиент RPC, который должен быть помечен как «reliable» или «unreliable«!

UFUNCTION(Client, unreliable)
void ClientRPCFunction();

Multicast RPC также должен быть помечен как «reliable» или «unreliable«!

UFUNCTION(NetMulticast, unreliable)
void MulticastRPCFunction();

Конечно же мы можем добавить ключевое слово reliable в RPC, чтобы сделать его важным.

UFUNCTION(Client, reliable)
void ReliableClientRPCFunction();
Validation (C++)
Идея проверки в том, что если функция проверки для RPC определяет, что какой-либо из параметров плохой, она может уведомить систему, чтобы отсоединить клиент/сервер, который инициировал вызов RPC.

На данный момент проверка требуется в каждой ServerRPCFunction. Для этого используйте ключевое слово WithValidation в макросе UFUNCTION.

UFUNCTION(Server, unreliable, WithValidation)
void SomeRPCFunction(int32 AddHealth);

Пример того, как можно использовать функцию _Validate.

bool ATestPlayerCharacter::SomeRPCFunction_Validate(int32 AddHealth) {
if(AddHealth > MAX_ADD_HEALTH) {
return false; // This will disconnect the caller!
}
return true; // This will allow the RPC to be called!
}
Примечание: Клиент от Server RPCs требует функцию «_Validate» для поддержки безопасноти функций Server RPC, чтобы сделать его как можно проще для кого-то, чтобы добавить код для проверки каждого параметра, чтобы быть действительным против всех известных входных ограничений!
Сделал — Cedric ‘eXi’ Neukirchen ( cedric.bnslv.de )
Актуально для Unreal Engine 4 Version: 4.11.
Перевёл на великий и могучий — RedComrade
Оригинал
Если вы нашли какую-либо ошибку в текстах перевода, просьба, напишите об этом в ЭТОЙ теме.

Читайте также: