HandleNetworkFailure

在 UE 中当网络连接出现错误时会调用 UEngine::HandleNetworkFailure 来接收错误消息和处理错误,错误的类型为枚举 ENetworkFailure::Type, 标识了几种网络的错误类型。
以 Server 拒绝玩家的加入为例,在 UE 的这套网络架构中,使用 CreateSession/JoinSession 的方式来创建 / 加入游戏,可以通过 AGameModeBase::Prelogin 以及 overwrite 了该成员函数的子类来拒绝玩家的加入,方法为返回的 ErrorMessage 不为空即为拒绝:

1
2
3
4
5
6
7
8
9
10
/**
* Accept or reject a player attempting to join the server. Fails login if you set the ErrorMessage to a non-empty string.
* PreLogin is called before Login. Significant game time may pass before Login is called
*
* @param Options The URL options (e.g. name/spectator) the player has passed
* @param Address The network address of the player
* @param UniqueId The unique id the player has passed to the server
* @param ErrorMessage When set to a non-empty value, the player will be rejected using the error message set
*/
virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);

GameMode 的 PreLogin 调用栈为:

当玩家被拒绝加入游戏时,服务器会发送给当前连接的客户端错误消息:

1
2
3
// call in server send to client
// function is UWorld::NotifyControlMessage
FNetControlMessage<NMT_Failure>::Send(Connection, ErrorMsg);

PS:FNetControlMessage<T>::Send的实现是由 DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM 宏包裹的,其定义在文件 DataChannel.h 中。
该消息会发送到客户端上,通过 UEngine::HandleNetworkError 来使客户端来处理该错误,在其中会通知到 UGameInstance::HandleNetworkError,但是并没有把ErrorMessage 传递给 GameInstance, 我们可以通过继承 UGameEngine 重写 HandleNetworkError 来将 ErrorMessage 传递给外部。

PS: 玩家被拒绝之后会回到项目设置里的 Game Default Map 中。