OnSessionListInServer 이후 게임시작이 안됨 지금 며칠째 같은걸로 문의중?

문의 응대 : 평일 오전 10시 ~ 오후 6시
문의를 남기실 경우 다음 항목을 작성해 주세요.
정보가 부족하거나 응대시간 외 문의하는 경우 확인 및 답변이 지연될 수 있습니다.

  • 뒤끝 SDK 버전 :
  • 프로젝트명 :
  • 스테이터스 코드 :
  • 에러 코드 :
  • 에러 메시지 :

프로젝트명 머니게임이고요 방금 막 일어난 매칭입니다.
6시 25분

제가 로그 조사 해댤라고 몇번이나 말했는데 끝까지 안해주시네요 오류 코드같은거 나온 적 없고
OnSessionListInServer 까지 정상적으로 동작하는것 확인했습니다
근데 OnMatchInGameStart가 실행이 안됩니다


코드상 OnSessionListInServer 내부의
MatchDoor.instance.isClose(true);

가 실행이 된건 확실히 확인했는데

Backend.Match.OnMatchInGameStart = () =>
{
op.allowSceneActivation = true;
};

오류는 안났는데 게임시작부분 실행이 안된다고요 애들 게임방에 입장까지 했는데 간혈적으로 게임시작이 안된다고요 특히 겜 접속직후 매칭했을때. 제발 버그면 버그라고 하고 고쳐주시던가요. 왜 대체 로그조사 안해주세요?

안녕하세요 개발자님,
우선 답변이 지연된 점 대단히 죄송합니다.

로그를 확인해본 결과, 전에 문의주신 내용에 대한 답변과 마찬가지로 아래와 같은 에러가 발생하는 현상이 파악되고 있습니다.
CreateMatchRoom → You have already joined the room.(방 생성 후 다시 방 생성을 요청할 경우)
RequestMatchMaking → Request Already matchmaking in-progress. (매치 신청 상태에서 요청을 한번 더 보낸 경우)

해당 에러가 현재 문제가 발생하여 매칭이 원활히 실행되지 않는지는 확인이 필요할 것 같습니다.
해당 함수들을 연속적으로 호출한다거나 에러가 확인된 적이 있으셨을까요?

근데 방 생성이나 매칭신청 중복 문제라면, 아예 매치메이킹이 되지 않아야 하는 것 아닌가요?
이미 매칭까지 성사 되었으며, 게임방 내의 유저들의 세션 아이디까지 정상적으로 다 받았습니다.이런 경우에는 그런 문제가 아니지 않나요?

매칭까지 완벽하게 이루어졌는데 Backend.Match.OnMatchInGameStart<<<< 이함수 하나만 실행이 안되는겁니다

방 생성이나 매칭 신청이 중복으로 되었을 경우, 처음 등록된 방 신청과 매칭 신청을 기준으로 요청이 진행됩니다.

만약 해당 에러 로그들이 개발하신 게임에서 발생이 불가능한 에러들(버튼 클릭 시 응답이 올동안 버튼 클릭 불가 구현등)이라면 해당 로그들도 인게임 접속과는 관계가 없어보이지만 이상현상으로 확인이 필요할 것 같아 말씀드렸습니다.

19일 토요일 관련 에러 로그를 조사해 보았을 때 게임방 접속 관련 해서 발생한 에러와 OnMatchInGameStart에 관한 에러 정보를 찾을 수 없어,
현재로서는 코드 구성과 해당 에러가 발생할 만한 요인을 추정하고 뒤끝 내부에서 테스트를 통해 원인 파악이 해야할 것 같습니다.

이와 관련해서 현재 게임에 적용된 뒤끝 매치에 대한 코드 공유가 가능하시다면 공유해주시면 더 빠르게 원인 파악이 가능할 것 같습니다.

만약 괜찮으시다면 공유해주시면 감사하겠으며, 아래 사항에 대한 정보 공유해 주시면 감사하겠습니다.

  1. 매칭 인원이 2명일 경우에도 일어나는지 혹은 8명일 경우에만 발생하는지
  2. 해당 현상 발생 시, 한 유저에게만 발생하는지 혹은 같이 매칭이 잡힌 모든 유저에게 발생하는지
  3. 해당 현상이 첫번째 게임에도 발생하는지 혹은 첫번째 게임 정상 완료 후 두번째 게임부터만 발생하는지

1.개발 초기에 유저가 2명인 경우로 테스트 했을 때도 일어났습니다.

2.같이 매칭잡힌 유저 모두에게 발생합니다.

  1. 첫번째 게임에서 발생하여 재접속 하면 정상 매칭되고, 그다음 매칭부턴 또 안되고 재접속 하면 되고를 반복 하는 것 같습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BackEnd;
using BackEnd.Tcp;
using UnityEngine.SceneManagement;

public class BackEndMatch : MonoBehaviour
{
    ErrorInfo errorinfo;
    [SerializeField]
    bool isConnectMatchServer;
    string RoomToken;
    WaitForSeconds repeatTime = new WaitForSeconds(0.1f);
    MatchUserGameRecord MyStartData,EnemyStartData;
    [SerializeField]
    GameObject WaitStartGame;

    AsyncOperation op;
    private void Awake()
    {
        {
            //WaitStartGame.SetActive(true);
            //GameObject.FindWithTag("MyStart").GetComponent<StartProfile>().Init("운영자", 1024, Skin.None);
            //GameObject.FindWithTag("EnemyStart").GetComponent<StartProfile>().Init("시", 1402, Skin.None);
        }
        try//전판 인게임서버에서 나오지 못했을 경우를 대비
        {
            Backend.Match.LeaveGameServer();
        }
        catch
        {

        }

        StartCoroutine(Poller());

        Matchready();

        Backend.Match.OnMatchMakingRoomCreate = (args) =>
        {
            print("매칭룸");
        };


        Backend.Match.OnMatchMakingResponse = (args) =>
        {
            print(args.ErrInfo);
            switch(args.ErrInfo)
            {
                case ErrorCode.Match_InProgress:
                    print("매칭 신청 성공");
                    MatchingEventScript.Instance.MatchMaking();
                    break;

                case ErrorCode.Success:
                    print("매칭 성공");
                    JoinInGameServer(args.RoomInfo.m_inGameServerEndPoint.m_address, args.RoomInfo.m_inGameServerEndPoint.m_port);//1단계
                    RoomToken = args.RoomInfo.m_inGameRoomToken;//인게임 서버접속시 안쓰이고 게임방 입장에 쓰임
                    
                    break;

                case ErrorCode.Match_MatchMakingCanceled:
                    print("매칭 취소");
                    MatchingEventScript.Instance.MatchMakingStop();
                    break;

                default:
                    print(args.ErrInfo);
                    break;

                   
            }


            
        };

        void JoinInGameServer(string serverAddress,ushort serverPort ) // 임의의 함수
        {
            bool isReconnect = false;//재접속한건지. 디폴트값은 false
            //ErrorInfo errorInfo = null;

            if(!Backend.Match.JoinGameServer(serverAddress, serverPort, isReconnect, out ErrorInfo errorInfo))//2단계
                StopMatching();

        }

        Backend.Match.OnSessionJoinInServer = (args) => {
            Backend.Match.JoinGameRoom(RoomToken);//3단계
        };

        Backend.Match.OnMatchMakingRoomCreate = (args) =>
         {
             Backend.Match.RequestMatchMaking(MatchType.Random, MatchModeType.OneOnOne, "2022-02-10T04:34:45.143Z");
         };
        Backend.Match.OnSessionListInServer = (args) =>//겜방 들어가자마자
        {

            MatchDoor.instance.isClose(true);
            op = SceneManager.LoadSceneAsync("Ingame");
            op.allowSceneActivation = false;

            CharacterFromWeb.Instance.userRecord = new List<MatchUserGameRecord>(args.GameRecords);
            foreach (var a in args.GameRecords)
            {
                print(a.m_sessionId);
            }

            if(args.GameRecords.Count==CharacterFromWeb.FullCount)
            {
                CharacterFromWeb.Instance.isLast = true;
                print("im last");
                CharacterFromWeb.Instance.SetUserCharacters(2);
            }
        };
        Backend.Match.OnMatchInGameAccess = (args) =>//다른애들 들어올 때마다
        {
            print(args.GameRecord.m_sessionId);
            if (!CharacterFromWeb.Instance.userRecord.Exists(x=>x.m_nickname==args.GameRecord.m_nickname))//중복시 넣지않음
                CharacterFromWeb.Instance.userRecord.Add(args.GameRecord);
        };





        Backend.Match.OnMatchInGameStart = () =>
        {
            op.allowSceneActivation = true;
        };

        Backend.Match.OnJoinMatchMakingServer = (args) =>
        {
            isConnectMatchServer = true;
            print("매칭서버 입장(람다식)");

        };
        Backend.Match.OnLeaveMatchMakingServer = (args) =>
        {
            isConnectMatchServer = false;
            print("매칭서버 퇴장(람다식)");
        };
    }
    public void Matchready()
    {
        if (Backend.Match.JoinMatchMakingServer(out errorinfo))
        {
            Debug.Log("매칭서버진입성공");
            Debug.Log(errorinfo);
        }
        else
        {
            Debug.Log("에러");
            Debug.Log(errorinfo);
        }
      
    }

    public void FastMatchMaking()
    {
        //if (!isConnectMatchServer)
        // Matchready();
        try
        {
                Backend.Match.CreateMatchRoom();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
            SceneManager.LoadScene("startscene");
        }
    }


    public void StopMatching()
    {
        Backend.Match.CancelMatchMaking();
    }


    IEnumerator Poller()
    {
        while(true)
        {
            Backend.Match.Poll();
            //print(Backend.Match.Poll());
            yield return repeatTime;
        }
    }

    private void OnDestroy()
    {

        Backend.Match.LeaveMatchRoom();
    }
}

답변 언제 되나요?

안녕하세요 개발자님.

현재 제공해주신 구현 코드를 참고하여 매칭 인원이 8명이라는 가정하에 테스트를 진행하고 있습니다.
허나 테스트상에서는 문제가 재현되지 않아 추가적으로 SDK에서 발생하는 에러케이스의 확인이 필요할 것 같습니다.

아래와 같이 개발자님이 보내주신 기존 코드에서 에러 로그로 확인이 불가한 부분에 에러가 발생할만한 부분에 Debug.Log 조치를 취했습니다.

아래 코드를 이용하여 플레이 중 동일 증상이 발생하신다면 빠르게 에러케이스와 로그 대조하여 확인해보도록 하곘습니다. 명쾌한 해결 방법 드리지 못하여 죄송합니다.(추가된 코드는 [뒤끝] 디버깅 주석 참조)

  • OnJoinMatchMaking에서 에러가 발생하여 CreateRoom이 안되는 케이스를 위한 Debug.Log(Not Connected 발생 부분)
  • 접속한 세션에 문제가 발생하여 OnSessionJoinInServer에서 에러하는 것을 확인하기 위한 Debug.Log
  • OnMatchInGameStart 호출을 확인하기 위한 Debug.Log
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using BackEnd;
using BackEnd.Tcp;
using UnityEngine.SceneManagement;

public class BackEndMatch : MonoBehaviour
{
    ErrorInfo errorinfo;
    [SerializeField]
    bool isConnectMatchServer;
    string RoomToken;
    WaitForSeconds repeatTime = new WaitForSeconds(0.1f);
    MatchUserGameRecord MyStartData, EnemyStartData;
    [SerializeField]
    GameObject WaitStartGame;

    AsyncOperation op;

    bool isReCreateMatchRoom = false;
    private void Awake()
    {
        {
            //WaitStartGame.SetActive(true);
            //GameObject.FindWithTag("MyStart").GetComponent<StartProfile>().Init("운영자", 1024, Skin.None);
            //GameObject.FindWithTag("EnemyStart").GetComponent<StartProfile>().Init("시", 1402, Skin.None);
        }
        try//전판 인게임서버에서 나오지 못했을 경우를 대비
        {
            Backend.Match.LeaveGameServer();
        }
        catch
        {

        }

        //StartCoroutine(Poller());

        Matchready();

        Backend.Match.OnMatchMakingRoomCreate = (args) =>
        {
            Debug.Log("OnMatchMakingRoomCreate : " + args.ErrInfo); // [뒤끝] - 디버깅

            print("매칭룸");
        };


        Backend.Match.OnMatchMakingResponse = (args) =>
        {
            print(args.ErrInfo);
            switch (args.ErrInfo)
            {
                case ErrorCode.Match_InProgress:
                    print("매칭 신청 성공");
                    MatchingEventScript.Instance.MatchMaking();
                    break;

                case ErrorCode.Success:
                    print("매칭 성공");
                    JoinInGameServer(args.RoomInfo.m_inGameServerEndPoint.m_address, args.RoomInfo.m_inGameServerEndPoint.m_port);//1단계
                    RoomToken = args.RoomInfo.m_inGameRoomToken;//인게임 서버접속시 안쓰이고 게임방 입장에 쓰임

                    break;

                case ErrorCode.Match_MatchMakingCanceled:
                    print("매칭 취소");
                    MatchingEventScript.Instance.MatchMakingStop();
                    break;

                default:
                    print(args.ErrInfo);
                    break;
            }
        };
        void JoinInGameServer(string serverAddress, ushort serverPort) // 임의의 함수
        {
            bool isReconnect = false;//재접속한건지. 디폴트값은 false
            //ErrorInfo errorInfo = null;

            if (!Backend.Match.JoinGameServer(serverAddress, serverPort, isReconnect, out ErrorInfo errorInfo))//2단계
                StopMatching();

        }
        Backend.Match.OnSessionJoinInServer = (args) =>
        {
            if (args.ErrInfo != ErrorInfo.Success)
            {
                Debug.LogError(args.ErrInfo);  // [뒤끝] - 디버깅
            }
            Backend.Match.JoinGameRoom(RoomToken);//3단계
        };

        Backend.Match.OnMatchMakingRoomCreate = (args) =>
         {
             isReCreateMatchRoom = false;
             Backend.Match.RequestMatchMaking(MatchType.Random, MatchModeType.OneOnOne, "2022-02-10T04:34:45.143Z");
         };
        Backend.Match.OnSessionListInServer = (args) =>//겜방 들어가자마자
        {

            MatchDoor.instance.isClose(true);
            op = SceneManager.LoadSceneAsync("Ingame");
            op.allowSceneActivation = false;

            CharacterFromWeb.Instance.userRecord = new List<MatchUserGameRecord>(args.GameRecords);
            foreach (var a in args.GameRecords)
            {
                print(a.m_sessionId);
            }

            if (args.GameRecords.Count == CharacterFromWeb.FullCount)
            {
                CharacterFromWeb.Instance.isLast = true;
                print("im last");
                CharacterFromWeb.Instance.SetUserCharacters(2);
            }
        };
        Backend.Match.OnMatchInGameAccess = (args) =>//다른애들 들어올 때마다
        {
            print(args.GameRecord.m_sessionId);
            if (!CharacterFromWeb.Instance.userRecord.Exists(x => x.m_nickname == args.GameRecord.m_nickname))//중복시 넣지않음
                CharacterFromWeb.Instance.userRecord.Add(args.GameRecord);
        };
        Backend.Match.OnMatchInGameStart = () =>
        {
            Debug.Log("OnMatchInGameStart 호출");   // [뒤끝] - 디버깅
            op.allowSceneActivation = true;
        };

        Backend.Match.OnJoinMatchMakingServer = (args) =>
        {
            if (args.ErrInfo != ErrorInfo.Success)
            {
                Debug.LogError($"OnJoinMatchMakingServer : {args.ErrInfo}");   // [뒤끝] - 디버깅
            }

            isConnectMatchServer = true;
            print("매칭서버 입장(람다식)");

            if (isReCreateMatchRoom)
            {
                FastMatchMaking();
            }
        };
        Backend.Match.OnLeaveMatchMakingServer = (args) =>
        {
            if (args.ErrInfo != ErrorInfo.Success)
            {
                Debug.LogError($"OnLeaveMatchMakingServer : {args.ErrInfo}");   // [뒤끝] - 디버깅
            }
            isConnectMatchServer = false;
            print("매칭서버 퇴장(람다식)");

            if (isReCreateMatchRoom)
            {
                Matchready();
            }
        };
    }

    void Poll()
    {
        Backend.Match.Poll();
    }

    public void Matchready()
    {
        if (Backend.Match.JoinMatchMakingServer(out errorinfo))
        {
            Debug.Log("매칭서버진입성공");
            Debug.Log(errorinfo);
        }
        else
        {
            Debug.LogError($"에러 : {errorinfo.ToString()}");   // [뒤끝] - 디버깅
            Debug.Log(errorinfo);
            isReCreateMatchRoom = false;
        }

    }

    public void FastMatchMaking()
    {
        //if (!isConnectMatchServer)
        // Matchready();
        try
        {
            Backend.Match.CreateMatchRoom();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
            ReCreateMatchRoom();
            //SceneManager.LoadScene("startscene");
        }
    }

    public void ReCreateMatchRoom()
    {
        isReCreateMatchRoom = true;
        Backend.Match.LeaveMatchMakingServer();
    }


    public void StopMatching()
    {
        Backend.Match.CancelMatchMaking();
    }


    // IEnumerator Poller()
    // {
    //     while (true)
    //     {
    //         Backend.Match.Poll();
    //         //print(Backend.Match.Poll());
    //         yield return repeatTime;
    //     }
    // }

    private void OnDestroy()
    {
        Backend.Match.LeaveMatchRoom();
    }

}