I am using PhotonFusion and Playfab. To manage session data, I use Azure Functions with cosmos DB.
At first PhotonFusion client make strings of session for PhotonFusion, then insert to cosmos DB. Next PhotonFusion server get the session strings and startgames.
I build as Docker image. When I checked on Local, client and server are good. But when I upload image(docker push), server status become Unhealthy.
So I checked the server to connect ssh.
I found docker images, but didn't boot container.
I did docker run command. So the image could boot. But status was still Unhealthy.
To keep status "Stanby", how I change the code?
namespace Fusion.Sample.DedicatedServer
{
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using PlayFab;
using Fusion.Photon.Realtime;
using Fusion.Sockets;
using System.Collections;
using System.Threading.Tasks;
using System.Net;
using PlayFab.ClientModels;
public class ServerManager : MonoBehaviour
{
public class ResultFromFunctions
{
public string session_id;
}
[SerializeField] private NetworkRunner _runnerPrefab;
public bool Debugging = true;
private AuthenticationValues AuthValues = new AuthenticationValues();
private string admin_email = "XXXXXXXXX";
private string admin_passwd = "XXXXXXXX";
private string _playFabPlayerIdCache;
private string session_id;
private string session_type = "entrance";
private void Start() {
Debug.Log("ServerManager Start");
if (CommandLineUtils.IsHeadlessMode() == false)
{
if (session_type == "entrance")
{
SceneManager.LoadScene((int)SceneDefs.MENUFORENTRANCE, LoadSceneMode.Single);
}
else
{
SceneManager.LoadScene((int)SceneDefs.MENUFORGAME, LoadSceneMode.Single);
}
return;
}
//
//PlayfabLogin
//↓
//RequestPhotonToken
//↓
//AuthenticateWithPhoton
//↓
//GetEntranceSession
//↓
//StartFusion();
PlayFabClientAPI.LoginWithEmailAddress(new LoginWithEmailAddressRequest
{
Email = admin_email,
Password = admin_passwd,
}, RequestPhotonToken, OnPlayFabError);
}
public void GetSession()
{
PlayFabCloudScriptAPI.ExecuteFunction(new PlayFab.CloudScriptModels.ExecuteFunctionRequest()
{
Entity = new PlayFab.CloudScriptModels.EntityKey()
{
Id = PlayFabSettings.staticPlayer.EntityId,
Type = PlayFabSettings.staticPlayer.EntityType
},
FunctionName = (session_type == "entrance") ? "GetEntranceSession" : "GetGameSession",
FunctionParameter = null,
GeneratePlayStreamEvent = true
}, result =>
{
if (result.FunctionResultTooLarge != null && (bool)result.FunctionResultTooLarge)
{
Debug.Log("Azure Functions から返される制限を超えた場合に発生する可能性があります。");
return;
}
Debug.Log($"{result.FunctionName} は " + $"{result.ExecutionTimeMilliseconds} ms で完了しました。");
Debug.Log($"返り値: {result.FunctionResult}");
ResultFromFunctions resultFromFunctions = JsonUtility.FromJson<ResultFromFunctions>(result.FunctionResult.ToString());
Debug.Log(resultFromFunctions.session_id);
session_id = resultFromFunctions.session_id;
Debug.Log($"session_id: {session_id}");
if (!string.IsNullOrEmpty(session_id))
{
StartFusion();
}
else
{
Log.Debug($"StartFusion-> not found session_id");
Application.Quit(1);
}
}, error =>
{
Debug.Log(error.GenerateErrorReport());
});
}
public void UpdateSession()
{
PlayFabCloudScriptAPI.ExecuteFunction(new PlayFab.CloudScriptModels.ExecuteFunctionRequest()
{
Entity = new PlayFab.CloudScriptModels.EntityKey()
{
Id = PlayFabSettings.staticPlayer.EntityId,
Type = PlayFabSettings.staticPlayer.EntityType
},
FunctionName = (session_type == "entrance") ? "UpdateEntranceSession" : "UpdateGameSession",
FunctionParameter = new Dictionary<string, object>()
{
{ "session_id", session_id }
},
GeneratePlayStreamEvent = true
}, result =>
{
if (result.FunctionResultTooLarge != null && (bool)result.FunctionResultTooLarge)
{
Debug.Log("Azure Functions から返される制限を超えた場合に発生する可能性があります。");
return;
}
Debug.Log($"{result.FunctionName} は " + $"{result.ExecutionTimeMilliseconds} ms で完了しました。");
Debug.Log($"返り値: {result.FunctionResult}");
//StartFusion();
}, error =>
{
Debug.Log(error.GenerateErrorReport());
});
}
IEnumerator ReadyForPlayers()
{
Debug.Log("ServerManager ReadyForPlayers");
yield return new WaitForSeconds(.5f);
PlayFabMultiplayerAgentAPI.ReadyForPlayers();
}
private void OnServerActive()
{
Debug.Log("ServerManager OnServerActive");
StartFusion();
}
private void RequestPhotonToken(PlayFab.ClientModels.LoginResult obj)
{
Debug.Log("PlayFab authenticated. Requesting photon token...");
_playFabPlayerIdCache = obj.PlayFabId;
PlayFabClientAPI.GetPhotonAuthenticationToken(new GetPhotonAuthenticationTokenRequest()
{
PhotonApplicationId = PhotonAppSettings.Instance.AppSettings.AppIdFusion
}, AuthenticateWithPhoton, OnPlayFabError);
}
private void AuthenticateWithPhoton(GetPhotonAuthenticationTokenResult obj)
{
Debug.Log("Photon token acquired: " + obj.PhotonCustomAuthenticationToken + " Authentication complete.");
AuthValues.AuthType = CustomAuthenticationType.Custom;
AuthValues.AddAuthParameter("username", _playFabPlayerIdCache);
AuthValues.AddAuthParameter("token", obj.PhotonCustomAuthenticationToken);
AuthValues.UserId = _playFabPlayerIdCache;
GetSession();
}
private void OnPlayFabError(PlayFab.PlayFabError obj)
{
Debug.Log(obj.GenerateErrorReport());
}
async void StartFusion() {
Debug.Log("ServerManager StartFusion");
Application.targetFrameRate = 30;
var config = DedicatedServerConfig.Resolve();
var runner = Instantiate(_runnerPrefab);
var result = await StartSimulation(
runner,
session_id,//config.SessionName,
config.SessionProperties,
config.Port,
config.Lobby,
config.Region,
config.PublicIP,
config.PublicPort
);
if (result.Ok) {
Log.Debug($"StartFusion-> Runner Start DONE");
Log.Debug("SessionName " + session_id + " -> requested");
UpdateSession();
}
else {
Log.Debug($"StartFusion-> Error while starting Server: {result.ShutdownReason}");
Application.Quit(1);
}
}
private Task<StartGameResult> StartSimulation(
NetworkRunner runner,
string SessionName,
Dictionary<string, SessionProperty> customProps,
ushort port,
string customLobby,
string customRegion,
string customPublicIP = null,
ushort customPublicPort = 0
) {
var photonSettings = PhotonAppSettings.Instance.AppSettings.GetCopy();
if (string.IsNullOrEmpty(customRegion) == false) {
photonSettings.FixedRegion = customRegion.ToLower();
}
// Build Custom External Addr
NetAddress? externalAddr = null;
if (string.IsNullOrEmpty(customPublicIP) == false && customPublicPort > 0) {
if (IPAddress.TryParse(customPublicIP, out var _)) {
externalAddr = NetAddress.CreateFromIpPort(customPublicIP, customPublicPort);
} else {
Log.Warn("Unable to parse 'Custom Public IP'");
}
}
return runner.StartGame(new StartGameArgs() {
SessionName = SessionName,
GameMode = GameMode.Server,
SceneManager = runner.gameObject.AddComponent<NetworkSceneManagerDefault>(),
Scene = (session_type == "entrance") ? (int)SceneDefs.MENUFORENTRANCE : (int)SceneDefs.MENUFORGAME,
SessionProperties = customProps,
Address = NetAddress.Any(port),
CustomPublicAddress = externalAddr,
CustomLobbyName = customLobby,
CustomPhotonAppSettings = photonSettings,
AuthValues = AuthValues,
PlayerCount = 5
});
}
}
}