Allocated server had issues (query failure [DOWN]), stopping server and deallocating

Hello, I have Implemented the server query handler system, but still, I'm getting this error and my server shuts down after 3 minutes. I have attached the code below.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Unity.Services.Matchmaker.Models;
using Unity.Services.Multiplay;
using UnityEngine.Networking;
using Debug = UnityEngine.Debug;

namespace Matchplay.Server
{
    public class MultiplayAllocationService : IDisposable
    {
        IMultiplayService m_MultiplayService;
        MultiplayEventCallbacks m_Servercallbacks;
        IServerQueryHandler m_ServerCheckManager;
        IServerEvents m_ServerEvents;
        string m_AllocationId;
        bool m_LocalServerValuesChanged = false;
        CancellationTokenSource m_ServerCheckCancel;

        const string k_PayloadProxyUrl = "http://localhost:8086";

        public MultiplayAllocationService()
        {
            try
            {
                m_MultiplayService = MultiplayService.Instance;
                m_ServerCheckCancel = new CancellationTokenSource();
            }
            catch (Exception ex)
            {
                Debug.LogWarning($"Error creating Multiplay allocation service.\n{ex}");
            }
        }

        /// <summary>
        /// Should be wrapped in a timeout function
        /// </summary>
        public async Task<MatchmakingResults> SubscribeAndAwaitMatchmakerAllocation()
        {
            if (m_MultiplayService == null)
                return null;
            m_AllocationId = null;
            m_Servercallbacks = new MultiplayEventCallbacks();
            m_Servercallbacks.Allocate += OnMultiplayAllocation;
            m_ServerEvents = await m_MultiplayService.SubscribeToServerEventsAsync(m_Servercallbacks);

            var allocationID = await AwaitAllocationID();
            var mmPayload = await GetMatchmakerAllocationPayloadAsync();

            return mmPayload;
        }

        //The networked server is our source of truth for what is going on, so we update our multiplay check server with values from there.
        public async Task BeginServerCheck()
        {
            if (m_MultiplayService == null)
                return;
            m_ServerCheckManager = await m_MultiplayService.StartServerQueryHandlerAsync((ushort)10,
                "", "", "0", "");

#pragma warning disable 4014
            ServerCheckLoop(m_ServerCheckCancel.Token);
#pragma warning restore 4014
        }

        public void SetServerName(string name)
        {
            m_ServerCheckManager.ServerName = name;
            m_LocalServerValuesChanged = true;
        }

        public void SetBuildID(string id)
        {
            m_ServerCheckManager.BuildId = id;
            m_LocalServerValuesChanged = true;
        }

        public void SetMaxPlayers(ushort players)
        {
            m_ServerCheckManager.MaxPlayers = players;
        }

        public void SetPlayerCount(ushort count)
        {
            m_ServerCheckManager.CurrentPlayers = count;
            m_LocalServerValuesChanged = true;
        }

        public void AddPlayer()
        {
            m_ServerCheckManager.CurrentPlayers += 1;
            m_LocalServerValuesChanged = true;
        }

        public void RemovePlayer()
        {
            m_ServerCheckManager.CurrentPlayers -= 1;
            m_LocalServerValuesChanged = true;
        }

        public void SetMap(string newMap)
        {

            m_ServerCheckManager.Map = newMap;
            m_LocalServerValuesChanged = true;
        }

        public void SetMode(string mode)
        {

            m_ServerCheckManager.GameType = mode;
            m_LocalServerValuesChanged = true;
        }

        public void UpdateServerIfChanged()
        {
            if (m_LocalServerValuesChanged)
            {
                m_ServerCheckManager.UpdateServerCheck();
                m_LocalServerValuesChanged = false;
            }
        }

        async Task ServerCheckLoop(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                UpdateServerIfChanged();
                await Task.Delay(1000);
            }
        }

        async Task<string> AwaitAllocationID()
        {
            var config = m_MultiplayService.ServerConfig;
            Debug.Log($"Awaiting Allocation. Server Config is:\n" +
                $"-ServerID: {config.ServerId}\n" +
                $"-AllocationID: {config.AllocationId}\n" +
                $"-Port: {config.Port}\n" +
                $"-QPort: {config.QueryPort}\n" +
                $"-logs: {config.ServerLogDirectory}");

            //Waiting on OnMultiplayAllocation() event (Probably wont ever happen in a matchmaker scenario)
            while (string.IsNullOrEmpty(m_AllocationId))
            {
                var configID = config.AllocationId;

                if (!string.IsNullOrEmpty(configID) && string.IsNullOrEmpty(m_AllocationId))
                {
                    Debug.Log($"Config had AllocationID: {configID}");
                    m_AllocationId = configID;
                }

                await Task.Delay(100);
            }

            return m_AllocationId;
        }

        /// <summary>
        /// Get the Multiplay Allocation Payload for Matchmaker (using Multiplay SDK)
        /// </summary>
        /// <returns></returns>
        async Task<MatchmakingResults> GetMatchmakerAllocationPayloadAsync()
        {
            var payloadAllocation = await MultiplayService.Instance.GetPayloadAllocationFromJsonAs<MatchmakingResults>();
            var modelAsJson = JsonConvert.SerializeObject(payloadAllocation, Formatting.Indented);
            Debug.Log(nameof(GetMatchmakerAllocationPayloadAsync) + ":" + Environment.NewLine + modelAsJson);
            return payloadAllocation;
        }

        void OnMultiplayAllocation(MultiplayAllocation allocation)
        {
            Debug.Log($"OnAllocation: {allocation.AllocationId}");
            if (string.IsNullOrEmpty(allocation.AllocationId))
                return;
            m_AllocationId = allocation.AllocationId;
        }

        void OnMultiplayDeAllocation(MultiplayDeallocation deallocation)
        {
            Debug.Log(
                $"Multiplay Deallocated : ID: {deallocation.AllocationId}\nEvent: {deallocation.EventId}\nServer{deallocation.ServerId}");
        }

        void OnMultiplayError(MultiplayError error)
        {
            Debug.Log($"MultiplayError : {error.Reason}\n{error.Detail}");
        }

        public void Dispose()
        {
            if (m_Servercallbacks != null)
            {
                m_Servercallbacks.Allocate -= OnMultiplayAllocation;
                m_Servercallbacks.Deallocate -= OnMultiplayDeAllocation;
                m_Servercallbacks.Error -= OnMultiplayError;
            }

            if (m_ServerCheckCancel != null)
                m_ServerCheckCancel.Cancel();

            m_ServerEvents?.UnsubscribeAsync();
        }
    }

    public static class AllocationPayloadExtensions
    {
        public static string ToString(this MatchmakingResults payload)
        {
            StringBuilder payloadDescription = new StringBuilder();
            payloadDescription.AppendLine("Matchmaker Allocation Payload:");
            payloadDescription.AppendFormat("-QueueName: {0}\n", payload.QueueName);
            payloadDescription.AppendFormat("-PoolName: {0}\n", payload.PoolName);
            payloadDescription.AppendFormat("-ID: {0}\n", payload.BackfillTicketId);
            payloadDescription.AppendFormat("-Teams: {0}\n", payload.MatchProperties.Teams.Count);
            payloadDescription.AppendFormat("-Players: {0}\n", payload.MatchProperties.Players.Count);
            payloadDescription.AppendFormat("-Region: {0}\n", payload.MatchProperties.Region);
            return payloadDescription.ToString();
        }
    }
}
1 Like

Hi. I'm experencing the same problem: the server crashes after 3 minutes:

Dec 21, 2022, 3:32 PM GMT+1
6175853
Allocated server had issues (query failure [DOWN]), stopping server and deallocating
Dec 21, 2022, 3:31 PM GMT+1
6175853
Server having issues (query failure [DOWN]) for 120 seconds (Restarted 0 time(s))
Dec 21, 2022, 3:30 PM GMT+1
6175853
Server having issues (query failure [DOWN]) for 61 seconds (Restarted 0 time(s))
Dec 21, 2022, 3:28 PM GMT+1
6175853
Performed start using build configuration "protobuild01"

I tested both mono and il2cpp linux builds (dedicated server platform).
I'm using the matchplay code as a base for matchmaker.
If i run the server on localhost it works fine (both windows and linux server builds)
I think my server build doesn't need too much resources:

8678313--1169727--upload_2022-12-21_15-38-26.png

Log:

SetupPlayerPrefab Zebra435 color RGBA(0.700, 0.600, 0.100, 1.000)
Matchplay.Server.<SetupPlayerPrefab>d__18:MoveNext()
System.Threading.ExecutionContext:RunInternal(ExecutionContext, ContextCallback, Object, Boolean)
System.Runtime.CompilerServices.MoveNextRunner:Run()
UnityEngine.WorkRequest:Invoke()
UnityEngine.UnitySynchronizationContext:Exec()

Executing Unity Signal Handler

Setting up 1 worker threads for Enlighten.
Memory Statistics:
[ALLOC_TEMP_TLS] TLS Allocator
  StackAllocators :
    [ALLOC_TEMP_MAIN]
      Peak usage frame count: [0-1.0 KB]: 11904 frames, [2.0 KB-4.0 KB]: 2 frames, [4.0 KB-8.0 KB]: 156 frames, [8.0 KB-16.0 KB]: 1 frames, [16.0 KB-32.0 KB]: 1 frames, [32.0 KB-64.0 KB]: 2 frames, [2.0 MB-4.0 MB]: 1 frames
      Initial Block Size 4.0 MB
      Current Block Size 4.0 MB
      Peak Allocated Bytes 2.1 MB
      Overflow Count 0
    [ALLOC_TEMP_Loading.AsyncRead]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 128 B
      Overflow Count 0
    [ALLOC_TEMP_Loading.PreloadManager]
      Initial Block Size 256.0 KB
      Current Block Size 332.0 KB
      Peak Allocated Bytes 329.8 KB
      Overflow Count 4
    [ALLOC_TEMP_Background Job.Worker 8]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 9]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Job.Worker 0]
      Initial Block Size 256.0 KB
      Current Block Size 256.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 10]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 14]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 6]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 12]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_EnlightenWorker]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 15]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 1]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 2]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 7]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_AssetGarbageCollectorHelper]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 5]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 13]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 11]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 3]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 1
    [ALLOC_TEMP_Background Job.Worker 0]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 66 B
      Overflow Count 0
    [ALLOC_TEMP_Background Job.Worker 4]
      Initial Block Size 32.0 KB
      Current Block Size 32.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
    [ALLOC_TEMP_BatchDeleteObjects]
      Initial Block Size 64.0 KB
      Current Block Size 64.0 KB
      Peak Allocated Bytes 0 B
      Overflow Count 0
[ALLOC_DEFAULT] Dual Thread Allocator
  Peak main deferred allocation count 66
    [ALLOC_BUCKET]
      Large Block size 4.0 MB
      Used Block count 1
      Peak Allocated bytes 1.2 MB
    [ALLOC_DEFAULT_MAIN]
      Peak usage frame count: [4.0 MB-8.0 MB]: 16 frames, [8.0 MB-16.0 MB]: 12051 frames
      Requested Block Size 16.0 MB
      Peak Block count 1
      Peak Allocated memory 10.0 MB
      Peak Large allocation bytes 0 B
    [ALLOC_DEFAULT_THREAD]
      Peak usage frame count: [1.0 MB-2.0 MB]: 12067 frames
      Requested Block Size 16.0 MB
      Peak Block count 1
      Peak Allocated memory 1.4 MB
      Peak Large allocation bytes 0 B
[ALLOC_TEMP_JOB_1_FRAME]
  Initial Block Size 2.0 MB
  Used Block Count 1
  Overflow Count (too large) 0
  Overflow Count (full) 0
[ALLOC_TEMP_JOB_2_FRAMES]
  Initial Block Size 2.0 MB
  Used Block Count 1
  Overflow Count (too large) 0
  Overflow Count (full) 0
[ALLOC_TEMP_JOB_4_FRAMES (JobTemp)]
  Initial Block Size 2.0 MB
  Used Block Count 2
  Overflow Count (too large) 0
  Overflow Count (full) 0
[ALLOC_TEMP_JOB_ASYNC (Background)]
  Initial Block Size 1.0 MB
  Used Block Count 3
  Overflow Count (too large) 0
  Overflow Count (full) 0
[ALLOC_GFX] Dual Thread Allocator
  Peak main deferred allocation count 0
    [ALLOC_BUCKET]
      Large Block size 4.0 MB
      Used Block count 1
      Peak Allocated bytes 1.2 MB
    [ALLOC_GFX_MAIN]
      Peak usage frame count: [32.0 KB-64.0 KB]: 12066 frames, [64.0 KB-128.0 KB]: 1 frames
      Requested Block Size 16.0 MB
      Peak Block count 1
      Peak Allocated memory 108.7 KB
      Peak Large allocation bytes 0 B
    [ALLOC_GFX_THREAD]
      Peak usage frame count: [0.5 MB-1.0 MB]: 12067 frames
      Requested Block Size 16.0 MB
      Peak Block count 1
      Peak Allocated memory 0.5 MB
      Peak Large allocation bytes 0 B
[ALLOC_CACHEOBJECTS] Dual Thread Allocator
  Peak main deferred allocation count 0
    [ALLOC_BUCKET]
      Large Block size 4.0 MB
      Used Block count 1
      Peak Allocated bytes 1.2 MB
    [ALLOC_CACHEOBJECTS_MAIN]
      Peak usage frame count: [1.0 MB-2.0 MB]: 12067 frames
      Requested Block Size 4.0 MB
      Peak Block count 1
      Peak Allocated memory 1.1 MB
      Peak Large allocation bytes 0 B
    [ALLOC_CACHEOBJECTS_THREAD]
      Peak usage frame count: [0.5 MB-1.0 MB]: 12066 frames, [2.0 MB-4.0 MB]: 1 frames
      Requested Block Size 4.0 MB
      Peak Block count 1
      Peak Allocated memory 3.3 MB
      Peak Large allocation bytes 0 B
[ALLOC_TYPETREE] Dual Thread Allocator
  Peak main deferred allocation count 0
    [ALLOC_BUCKET]
      Large Block size 4.0 MB
      Used Block count 1
      Peak Allocated bytes 1.2 MB
    [ALLOC_TYPETREE_MAIN]
      Peak usage frame count: [0-1.0 KB]: 12067 frames
      Requested Block Size 2.0 MB
      Peak Block count 1
      Peak Allocated memory 1.0 KB
      Peak Large allocation bytes 0 B
    [ALLOC_TYPETREE_THREAD]
      Peak usage frame count: [4.0 KB-8.0 KB]: 12067 frames
      Requested Block Size 2.0 MB
      Peak Block count 1
      Peak Allocated memory 7.1 KB
      Peak Large allocation bytes 0 B

Output may be truncated for performance

Perhaps the problem could be in this function:

 public void UpdateServerIfChanged()
        {
            if (m_LocalServerValuesChanged)
            {
                m_ServerCheckManager.UpdateServerCheck();
                m_LocalServerValuesChanged = false;
            }
        }

We only send a query (SQP) when we have some "changes" like setmap, addplayer or RemovePlayer.
Acording documentation:
GSH relies on query protocol responses to determine server instances' health. If your build doesn’t support a query protocol or if you set up your query protocol incorrectly, GSH might determine your server instances are unresponsive.

Maybe if we dont send UpdateServerCheck for 3 minutes, GSH would determine that the server is unresponsive and it kill the instance.

It’s not the problem, I send the UpdateServerCheck more often, but I got the same result: a crash after 3-4 minutes. In Mono I get more info

Server exit: triggering deallocation (exit: 139, signal: terminated)
    "memorysetup-gfx-thread-allocator-block-size=16777216"
    "memorysetup-cache-allocator-block-size=4194304"
    "memorysetup-typetree-allocator-block-size=2097152"
    "memorysetup-profiler-bucket-allocator-granularity=16"
    "memorysetup-profiler-bucket-allocator-bucket-count=8"
    "memorysetup-profiler-bucket-allocator-block-size=4194304"
    "memorysetup-profiler-bucket-allocator-block-count=1"
    "memorysetup-profiler-allocator-block-size=16777216"
    "memorysetup-profiler-editor-allocator-block-size=1048576"
    "memorysetup-temp-allocator-size-main=4194304"
    "memorysetup-job-temp-allocator-block-size=2097152"
    "memorysetup-job-temp-allocator-block-size-background=1048576"
    "memorysetup-job-temp-allocator-reduction-small-platforms=262144"
    "memorysetup-temp-allocator-size-background-worker=32768"
    "memorysetup-temp-allocator-size-job-worker=262144"
    "memorysetup-temp-allocator-size-preload-manager=262144"
    "memorysetup-temp-allocator-size-nav-mesh-worker=65536"
    "memorysetup-temp-allocator-size-audio-worker=65536"
    "memorysetup-temp-allocator-size-cloud-worker=32768"
    "memorysetup-temp-allocator-size-gfx=262144"
Output may be truncated for performance
Caught fatal signal - signo:11 code:0 errno:0 addr:(nil)
Obtained 13 stack frames.
#0  0x007fc2ba505420 in funlockfile
#1  0x007fc2ba3dc23f in clock_nanosleep
#2  0x007fc2ba3e1ec7 in nanosleep
#3  0x007fc2bb2e8481 in std::_Rb_tree<void const*, void const*, std::_Identity<void const*>, std::less<void const*>, std::allocator<void const*> >::_M_erase(std::_Rb_tree_node<void const*>*)
#4  0x007fc2bb1ba523 in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#5  0x007fc2bb1ba5ea in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#6  0x007fc2bb20dff7 in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#7  0x007fc2bb2073a7 in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#8  0x007fc2bb207362 in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#9  0x007fc2bb20764c in int* std::_V2::__rotate<int*>(int*, int*, int*, std::random_access_iterator_tag)
#10 0x007fc2bb42e9a7 in PlayerMain(int, char**)
#11 0x007fc2ba323083 in __libc_start_main
#12 0x0056283de4c029 in (Unknown)

Output may be truncated for performance

Hello,

It is not clear from your code where the server query handler is being started. You have a task named BeginServerCheck, but this is not called anywhere (at least not in this class).

The StartServerQueryHandlerAsync method from the SDK needs to be called when the server starts. We have an example of this in the documentation (https://docs.unity.com/game-server-hosting/sdk/game-server-sdk-for-unity.html?hash=2542536344#Start_server_query_handler) where it is called by the Start method of a MonoBehaviour class.

Did you ever find a solution to your problem? It looks like as I’ve been learning I’ve taken a similar path to you and have been encountering the same problem.

I dont have any solution. The server crashes after some minutes, I read and checked the documentation lot of times

In my case, it’s the same code than matchplay sample: https://github.com/Unity-Technologies/com.unity.services.samples.matchplay

ApplicationController

Debug.Log("Initalizing Server....");
                var serverSingleton = Instantiate(m_ServerPrefab);
                await serverSingleton.CreateServer(); //run the init instead of relying on start.

                var defaultGameInfo = new GameInfo
                {
                    gameMode = GameMode.Meditating,
                    map = Map.Space,
                    gameQueue = GameQueue.Casual
                };

                await serverSingleton.Manager.StartGameServerAsync(defaultGameInfo);

ServerSingleton : Monobehaviour

 public async Task CreateServer()
        {
            await UnityServices.InitializeAsync();

            m_GameManager = new ServerGameManager(
                ApplicationData.IP(),
                ApplicationData.Port(),
                ApplicationData.QPort(),
                NetworkManager.Singleton);
        }

ServerGameManager

public async Task StartGameServerAsync(GameInfo startingGameInfo)
        {
            Debug.Log($"Starting server with:{startingGameInfo}.");

                  ....
                    await StartAllocationService(startingGameInfo,
                        (ushort)matchmakerPayload.MatchProperties.Players.Count);
                 .....
}

 async Task StartAllocationService(GameInfo startingGameInfo, ushort playerCount)
        {

            await m_MultiplayAllocationService.BeginServerCheck();

            //Create a unique name for the server to show that we are joining the same one

            m_MultiplayAllocationService.SetServerName(m_ServerName);
            m_MultiplayAllocationService.SetPlayerCount(playerCount);
            m_MultiplayAllocationService.SetMaxPlayers(10);
            m_MultiplayAllocationService.SetBuildID("0");
            m_MultiplayAllocationService.SetMap(startingGameInfo.map.ToString());
            m_MultiplayAllocationService.SetMode(startingGameInfo.gameMode.ToString());

         
        }
        }

MultiplayAllocationService

        public async Task BeginServerCheck()
        {
            if (m_MultiplayService == null)
                return;

            m_ServerCheckManager = await m_MultiplayService.StartServerQueryHandlerAsync((ushort)10,
                "", "", "0", "");

#pragma warning disable 4014
            ServerCheckLoop(m_ServerCheckCancel.Token);
#pragma warning restore 4014
        }

Follow up: The matchplay sample actually didn't work with sqp, and now might be fixed. (https://github.com/Unity-Technologies/com.unity.services.samples.matchplay) Take a look and you may be able to resolve your issues. There was a new commit for this issue about a week ago (2-6-23).

Hey guys, I solved the issue by updating the query every second and the server is functioning properly now !!

1 Like

I solved the issue too by implementing from scratch all the features: SQP, backfill matchmaking QoS....

1 Like

Hi, I have similar issue. I have called serverQueryHandler.UpdateServerCheck() in Update but server still crash. Anyone know what's wrong in my code?
This is my code, I called StartServerQuery() from another class.

public async Task StartMultiplay()
        {
            LogServerConfig();
            multiplayEventCallbacks = new MultiplayEventCallbacks();
            multiplayEventCallbacks.Allocate += OnAllocate;
            multiplayEventCallbacks.Deallocate += OnDeallocate;
            multiplayEventCallbacks.Error += OnError;
            multiplayEventCallbacks.SubscriptionStateChanged += OnSubscriptionStateChanged;

            await MultiplayService.Instance.SubscribeToServerEventsAsync(multiplayEventCallbacks);

            if (!string.IsNullOrEmpty(MultiplayService.Instance.ServerConfig.AllocationId))
            {
                await StartServer();
            }
        }

        public async Task StartServer()
        {
            matchmakingResults = await MultiplayService.Instance.GetPayloadAllocationFromJsonAs<MatchmakingResults>();

            string matchId = matchmakingResults.MatchId;
            Debug.Log("matchId: " + matchId);
        }

        public async Task StartServerQuery(SessionRequest session)
        {
            serverQueryHandler = await MultiplayService.Instance.StartServerQueryHandlerAsync((ushort)session.MaxPlayers, session.ServerName, session.Map, Application.version, session.CustomProperties["map"]);
            Debug.Log("StartServerQueryHandlerAsync");
        }

        public async void GameServerReady()
        {
            await MultiplayService.Instance.ReadyServerForPlayersAsync();
            Debug.Log("ReadyServerForPlayersAsync");
        }

        public void PlayerCountChanged(ushort newPlayerCount)
        {
            serverQueryHandler.CurrentPlayers = newPlayerCount;
            Debug.Log("ServerQueryHandler CurrentPlayers: " + newPlayerCount);
        }

        private void Update()
        {
            if (serverQueryHandler != null)
                serverQueryHandler.UpdateServerCheck();
        }

Fixed for me by adding UpdateServerCheck() in Update loop as well. I guess you don't need to do it that way. But I think at least one initial UpdateServerCheck() call is necessary after query handler init. That should be however stated in the documentation if that's the case

On my end, even updating the data every 5 seconds does not prevent the server from getting shut down.

EDIT: Changing that frequency from 5 seconds to 1 made everything work… How come?

Maybe they increased the polling on their side? So you have to be faster than their query

Having the same issue. Server is deallocated after several minutes. Although some sessions are working normally and not being interrupted. I'm calling UpdateServerCheck every 1 second.

What is the Events tab telling you? What are the reasons for the deallocation?

This is what I see in the events log:
Server having issues (Query didn't respond or responded incorrectly [NONAME]) for 120 seconds (Restarted 0 time(s))
and then
Allocated server had issues (Query didn't respond or responded incorrectly [NONAME]), stopping server and deallocating

In my log file I see:
SQP server: SQP server started on 0.0.0.0:9010
and also made sure I call UpdateServerCheck every 1 second

Hello,

The post from @Rachenite is correct, the matchplay sample did have an issue that meant it did not respond correctly to SQP. This was resolved in this pull request (fix: Resolves issues with server not responding to SQP by danmrichards · Pull Request #23 · Unity-Technologies/com.unity.services.samples.matchplay · GitHub) so please check that you are using the latest version of any code taken from here.

There were also some recent updates to documentation on SQP here - Game Server Hosting (Multiplay) SDK for Unity

I suggest calling UpdateServerCheck more frequently than every second, in the region of 100ms - 500ms should be fine. I suspect that you are seeing a race condition between your game server updating SQP and the Multiplay backend querying your server (which also happens every 60 seconds)

Thanks danri. The documentation suggests using the "Update" method for the update check calls and the sample uses a separate thread. What is the best practice? I'm not sure how intensive is this call and I want to make sure it won't affect my server performance. My current implementation is using the "Update" method.

In the meanwhile, I'll reduce to 100ms and tell you if it fixes my issue.

@spikyworm5 ah sorry I missed the part where you said you update every 1 second. I do update just every Update without a limit. That's why it worked for me I guess