WebGL에서 Unity Gaming Service를 연동하던 중, 익명 사용자로 로그인한 상태에서 브라우저 탭을 새 탭으로 변경하거나 최소화한 뒤 약 1분 30초 ~ 2분이 지나면 다음과 같은 에러가 발생했다.

 

<코드> 

    // Start is called before the first frame update
    async void Start()
    {
        try
        {
            await UnityServices.InitializeAsync();
            Debug.Log($"Unity Services의 초기화를 성공하였습니다., UnityServices.State: [{UnityServices.State}]");

            AuthenticationService.Instance.SwitchProfile(UserName);
            await AuthenticationService.Instance.SignInAnonymouslyAsync();
            Debug.Log($"Unity Services의 익명 사용자 계정으로 로그인을 성공하였습니다. PlayerName: {UserName}");
        }
        catch (ArgumentException e)
        {
            Console.WriteLine($"InitializeAsync Processing failed: {e.Message}");
        }
        catch (Exception e)
        {
            Debug.LogException(e);
        }
    }

 

<에러 내용>

 

에러 내용은 framework.js의 5079번째 줄에서 readState를 읽을 수 없다는 것이었다.

 

해당 내용을 확인하기 위해 Unity의 Build Settings에서 Development Build를 체크한 후 빌드했습니다. 이후, framework.js 파일에 콘솔 로그를 추가하고 브라우저의 개발자 모드에서 로그를 확인했다.

 

<Development Build 체크>

 

<콘솔 로그 작성>

framework.js 파일
에러난 부분에 위에 콘솔 로그 작성

 

<에러 내용 확인>

 

 

에러 내용에 보듯이 "instance.ws: undefined" 라고 적혀있다. 그 윗줄에 로그를 보면 instance에 ws: Websoket이 있지만 해당 에러가 발생한 시점에는 존재하지 않아서 undefined 로그를 출력하는걸 볼수 있었다. 

 

자 그럼 이제 _WebSocketSend의 함수의 코드를 보도록 하자.

여기서 문제는 5076번째 줄의 조건문은 undefined를 체크할 수가 없다. 찾아보니 자바스크립트는 null === undefined 는 false로 판정이 된다.

참고 블로그: 

https://tmdrnr96.tistory.com/27

 

[Javascript] ==와===의 차이

Javascript를 사용 중에 값을 비교해야 할 때가 있는데, 이때 비교연산자인 ==연산자와 ===연산자를 사용한다. 두 연산자 모두 비교한 피연산자 값이 일치하면 ture값을 반환하고 비교한 피연산자 값

tmdrnr96.tistory.com

 

그래서 다음과 같이 조건문을 instance.ws === null을 !instance.ws로 변경했다. 아 물론 instance == null을 사용해도 된다.

<코드>

 

<결과 확인>

 

Websocket is not connected 에러만 뜰뿐, 프로그램은 원할하게 작동된다. 

 

이제 여기서 Development Buld로 빌드하는 것이 아니라 일반 빌드를 해야지 최종 배포를 할 수 있을것이다.

 

찾다보니 나랑 비슷한 문제가 있었던 글을 발견했고 해결방법도 적혀있었다.

 

https://discussions.unity.com/t/strange-exception-in-webgl-build-when-tab-is-inactive/946640

 

대충 위의 글을 framework.js 압축을 해제해서 수정한 후 다시 압축하라는 것이였다.

 

그래서 나는 위의 글대로 압축을 해제하고 _WebSocketSend 함수를 찾아 if (instance.ws === null) 를 if(!instance.ws) 로 변경하고 7-zip을 사용하여 .gz 확장자로 다시 압축을 진행하고 실행하니까 정상적으로 작동하는걸 볼 수 있었다.

 

추가적으로 유니티에서 답변 받은 내용이 있어서 적는다.

압축을 위의 글 처럼 압축을 해제해서 변경한 뒤에 다시 압축할 필요 없이 Plugin의 jslib로 변경하는 방법이 있었다.

Packages폴더에서 Wire/Plugins/WebSocket.jslib 파일이 있다. 여기서 WebSocketSend를 찾아 변경하면은 정상적으로 작동되는걸 확인할 수 있다.

<파일 위치>

<코드 변경>

 

 

파일도 첨부 해놓는다.

WebSocket.jslib
0.01MB

 

 

이 버그는 언제 고쳐줄지는 모르겠지만 고치기 전까지는 이 방법을 써야겠다.

+ Recent posts