채팅 씬 전환 후 접속 오류

문의를 남기실 경우 다음 항목을 작성해 주시면 빠른 답변 처리에 도움이 됩니다.

  • 프로젝트명 : 무한의 기사
  • 뒤끝SDK 버전 : 5.4.4
  • 에러 코드 :

Chat 관리 클래스는 Singletone으로 구성 되어 있습니다.

첫 번 째 씬 진입 할 때는 채팅 기능에 문제가 없습니다. 채널 전환도 잘 됩니다.

문제는 다른 씬으로 변경 후 다시 채팅 서버에 접속 할 때 정상적으로 동작 하지 않습니다.

모든 접속 시도는

  1. 연결을 끊고

if (Backend.Chat != null && Backend.Chat.IsChatConnect(ChannelType.Public))
Backend.Chat.LeaveChannel(ChannelType.Public);
Backend.Chat.ResetConnect();

  1. 연결이 끊어져 있는지 확인 후

Backend.Chat.IsChatConnect(ChannelType.Public)

  1. 채널에 접속을 시도 합니다.

Backend.Chat.JoinChannel(ChannelType.Public

씬 전환 후 위의 과정을 첫 번 째 시도 하면

Backend.Chat.OnException : The object of type ‘GameObject’ has been destroyed but you are still trying to access it.

위와 같은 예외가 발생합니다.

위에도 적었지만 Backend.Chat.Poll(); 을 하는 클래스는 싱글톤으로 만들어져 있으므로

씬 전환이 되어도 삭제가 되지 않습니다.

첫 번 째 실패 후 두번 째 시도를 하면

Backend.Chat.JoinChannel → Category: DuplicateConnection, Detail: DuplicateConnection, SocketError: Success, Reason: Already Online

에러가 발생 합니다.

위의 경우도 1,2번을 통과 한 후의 Join 채널 시도입니다.

가끔은

OnJoinChannelFail = Category: Exception, Detail: DisconnectFromRemote, SocketError: Success, Reason: Can’t find channel. game id: 1783

오류도 보입니다.

지난 번에 연결을 완전히 끊어 주는 기능을 요청 했고, 그래서 만들어 진 것이

Backend.Chat.ResetConnect();

이것으로 알고 있는데, 이거 완전히 연결 초기화 되는 거 맞습니까?

확인 부탁드리겠습니다.

안녕하세요 개발자님.

씬 전환 후 Backend.Chat.Poll()를 포함한 싱글톤 클래스를 찾지 못하여 코드 발생하는 오류로 보입니다.

해당 코드 내의 싱글톤 구현방식을 알지 못해 확실히 답변드리기 어렵지만 DontDestroyOnLoad등으로 삭제를 막았는지, 싱글톤 내에 다른 함수 또는 변수도 씬 변경 시 접근이 가능한지 확인해주시면 감사하겠습니다.

LeaveChannel, ResetConnect은 Backend.Chat.Poll()이 호출되어야 초기화가 정상적으로 이루어지기 때문에 Poll이 호출이 되지 않아 연결중인 세션의 정보가 제거되지 않은 것으로 보입니다.

ResetConnect 함수는 현재 연결되어 있는 채널을 찾아 모두 종료 하는 함수로, LeaveChannel 호출 후에 바로 호출하는 것은 문제가 발생할 가능성이 있을 수 있습니다.
알맞은 형태의 뒤끝챗 함수를 정상적으로 호출을 했음에도 에러가 발생할 경우, ResetConnect()를 이용해 연결 종료하는 로직으로 구현해주시면 감사하겠습니다.

DontDestroyOnLoad 처리가 된 싱글톤 입니다.

한 번 만들어진 gameObject는 절대 파괴 되지 않게 되어 있습니다.

ResetConnect 는 문제가 해결 되지 않아서 추가로 넣어 본 코드입니다.

Backend.Chat.Poll() 은 최초 생성 부터 지속적으로 호출이 됩니다.

그렇다면 혹시 해당 변경된 씬 내에 오브젝트에 종속된 클래스에서 싱글톤 객체를 이용하거나, 반대로 싱글톤 객체에서 다른 클래스의 정보를 받아 사용하는 채팅 코드(JoinChannel에 들어가는 인자값등)가 있으실까요?

또한 해당 에러가 호출되는 시점(1번의 if문, 1번의 LeaveChannel)과
OnException의 Excetion 로그도 가능하다면 보내주시면 감사하겠습니다.

변경 된 씬에서는 아예 접근 하지 않습니다.
Chat관리 클래스는 외부 클래스의 정보를 받아 오지 않으며, 메인 씬에서 Chat 클래스에 접근 만 합니다.

  1. OnLeaveChannel : Category: Success, Detail: DisconnectFromLocal, SocketError: Success, Reason:
    UnityEngine.Debug:Log(Object)
    <>c:b__1_3(LeaveChannelEventArgs) (at Assets/Script/Game/Backend/BackendChatManager.cs:79)
    BackEnd.RealTime.GameChat:#su(LeaveChannelEventArgs)
    BackEnd.RealTime.GameChat:#5t(LeaveChannelEventArgs)
    BackEnd.Tcp.#6o:#5o()
    BackEnd.Tcp.TcpClient:#qn()
    BackEnd.Tcp.TcpClient:#rn()
    BackEnd.Tcp.TcpClient:Poll()
    BackEnd.RealTime.GameChat:Poll()
    BackendChatManager:Update() (at Assets/Script/Game/Backend/BackendChatManager.cs:390)

  2. Backend.Chat.OnException : The object of type ‘GameObject’ has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    UnityEngine.Debug:Log(Object)
    <>c:b__1_0(Exception) (at Assets/Script/Game/Backend/BackendChatManager.cs:26)
    BackEnd.RealTime.GameChat:#eu(Exception)
    BackEnd.Tcp.TcpClient:#qn()
    BackEnd.Tcp.TcpClient:#rn()
    BackEnd.Tcp.TcpClient:Poll()
    BackEnd.RealTime.GameChat:Poll()
    BackendChatManager:Update() (at Assets/Script/Game/Backend/BackendChatManager.cs:390)

재현도 쉽습니다.

그냥 최초 채널에 접속 후 연결 끊고, 씬 전환 한 이후 돌아와서 채널에 연결 시도

하면 연결이 안됩니다.

  1. 채팅 핸들러에 UI등에 접근할 수 있는 게임 오브젝트가 등록
  2. 씬 변경 후 게임 오브젝트 연결이 풀림
  3. OnLeaveChannel핸들러에서 연결된 게임 오브젝트를 찾지 못하여 OnException에서 에러 발생

이런 로직으로 에러가 발생하는 상황으로 추측이 됩니다.
씬 변경후에도 핸들러 설정을 해주는지 혹은 오브젝트를 찾을 수 있는지 확인해주시면 감사하겠습니다.

Backend.Chat.OnLeaveChannel = (args) =>
{
Debug.Log($“OnLeaveChannel : {args.ErrInfo}”);
if (args.ErrInfo == ErrorInfo.Success)
{
}

        if (!args.Session.IsRemote)
        {
            //Debug.Log("OnLeaveChannel");
            ChatOperator.tryChannelData = null;
            ChatOperator.onConnectChannel = false;
        }
    };

OnLeaveChannel 는 씬 전환 시 정상적으로 확인 됩니다. 위의 코드를 보면 알겠지만

게임 오브젝트 연결 된 게 없습니다.

다시 말씀 드리지만 챗 클래스 내에서 다른 게임 오브젝트 참조 되는게 없습니다.

채팅 메시지도 큐로 교환 되고 있습니다.

핸들러 설정은 클래스 생성 시 최초 한 번만 됩니다.

답변 주신 내용을 보고

이벤트 핸들러 코드를 확인 하는 중 OnJoinChannel 에 내부에서

호출 하는 이벤트 핸들러가 게임 오브젝트를 참조 하면서 발생 하는

오류로 확인 되었습니다.

제 실수 입니다.

문제 해결 되었습니다.

시간 내 주셔서 감사합니다.

좋아요 1