WebGL 백그라운드 탭
사용자들이 복수 브라우저 탭을 오픈 했을때는, 활성(보이는)탭 만이 고속으로 정기적으로 업데이트 됩니다.
비활성(보이지 않는)탭들은 대부분의 브라우저에서 1초에 한번 업데이트 될 뿐 입니다.
이 경우에 있어서 윈도우가 앞에 있는 가시성은 중요하지 않으며 또한 다른 윈도우에 의해 가려지거나 포커스가 없을 수도 있습니다.
이것은 Unity의 WebGL 익스포트에도 적용되며 수신 및 발신 메시지가 1초에 한 번만 처리되므로 문제가 발생 할 수 있습니다.
이 의미는 메시지 큐가 커지게되고 저속으로 업데이트가 되기 때문에 처리를 위해 더 많은 업데이트가 필요하다는 것입니다.
많은 앱들은 탭이 백그라운드에서 작동하는 동안 점점 더 많은 동기화가 이루어지지 않고 연결이 끊어집니다.
WebGL 어플리케이션은 JavaScript를 사용하기 때문에 브라우저에서 메시지를 게임 로직으로 직접 보내기 위해 이러한 빌드들을 확장 할 수 있습니다.
여기에는 게임에서 연결을 끊거나 어플리케이션 탭이 백그라운에 있을 때 낮은 업데이트 속도 사이에 추가 업데이트를 적용 할 수 있는 가능성을 포함하고 있습니다.
이렇게 하기 위해서는 다음의 접근법 중 하나를 따라 할 수 있습니다.
WebGL 빌드 변경
접근법에 대해서 이야기하기 전에 어플리케이션 탭이 백그라운드에 있는지를 결정하는 방법에 대해 먼저 살펴보도록 하겠습니다.
따라서 우리는visibilitychange
이벤트를 후킹하여 변경 사항을 리슨합니다.
다른 두 상태가 있습니다: hidden
과 "any other state".
상태 변화를 감지 할 때 마다 게임 로직에서 게임 객체에 메시지를 보내고 이런 방식으로 함수를 실행할 수 있습니다.
다음 JavaScript 코드 스니펫을 사용하여 보여 줄 수 있습니다.
JavaScript
<script>
document.addEventListener('visibilitychange', function () {
if (document.visibilityState == "hidden") {
SendMessage("Receiver", "DoSomething");
} else {
SendMessage("Receiver", "DoSomethingElse");
}
});
</script>
위의 경우에서 'Receiver' 라고 하는 게임 오브젝트에 메시지를 전송하고 있습니다.
이 객체에서는 DoSomething(Else)
라고 하는 함수를 실행하고 있습니다.
이 함수는 게임 객체에 붙여진 어떤 스크립트 내부에서도 위치 시킬 수 있습니다.
WebGL 어플리케이션에서 이 코드를 붙이기 위해서는 빌드를 탐색하여 생성된 index.html 파일을 오픈하세요.
위의 스니펫을 복사하여 붙일 수 있고 html 파일의 34 라인 <body>
태그 내부에 삽입합니다.
'SendMessage' 함수의 매개변수들을 조정하는 것을 잊지 마세요.
첫 번째 방법 - 연결 해제
첫 번째 방법은 WebGL 어플리케이션 탭이 백그라운드로 들어가면 클라이언트를 Photon에서 연결 해제하는 것 입니다.
이것은 어플리케이션이 포어그라운드로 다시 될 때, Photon으로 (재)연결을 시도할 것 입니다.
설명된 시나리오를 처리하기 위해 권장되는 방식입니다.
이렇게 하기 위해서는 index.html 파일에서 위에 나온 코드 스니펫을 사용하여 게임 로직에서 'Disconnect'및 'Reconnect' 함수로 메시지를 전송합니다.
이러한 함수는 다음의 예제와 같이 보일 것 입니다:
C#
public void Disconnect()
{
PhotonNetwork.Disconnect();
}
public void Reconnect()
{
if (!PhotonNetwork.connected && wasConnected)
{
PhotonNetwork.ReconnectAndRejoin();
}
else
{
PhotonNetwork.ConnectUsingSettings("1.0");
}
}
참고: 부울 변수wasConnected
는 클라이언트가 이전에 방에 들어 왔을 때 true로 설정됩니다.
이 정보를 가지고 있음으로써 먼서 로비에 참여하는 대신 룸에 다시연결하고 재참여를 직접 시도할 수 있습니다.
PlayerTtl
(플레이어가 서버에서 제거되기 전에 연결 해제 후 얼마나 오랫동안 비활성화 될 수 있는지를 나타냅니다. 단위 밀리초)를 0보다 큰 값으로 설정해야 한다는 의미입니다.
빈 룸을 유지하기 원하는 경우에는 EmptyRoomTtl
(서버에서 룸이 제거될 때 까지 얼마나 오랫동안 비어있는 룸을 유지할 것인지, 단위 밀리초)를 0보다 큰 값으로 설정해야 합니다.
이 방법을 사용하여 ReconnectAndRejoin
을 테스트 할 때는 두 값 모두 30,000 (30 초) 또는 심지어 60,000(60 초)로 설정하는 것이 좋을 것 입니다.
두 번째 방법 - 관심 그룹을 사용하고 연결을 살아있는 상태로 유지하기
두 번째 방법은 게임 로직 및 특히 네트워킹 로직에 대한 추가 작업이 필요합니다.
이 접근 방식을 사용하는 것은 게임 관련 메시지를 보내거나 받지 않고 연결을 계속 유지하는 것 입니다.
특정 그룹으로 부터의 빠른 구독 또는 구독해제를 하기 위해 관심 그룹을 사용하여 달성하는 것 입니다.
위에서 설명한 것처럼 이 방식을 사용할 때 다른 관심 그룹이 필요합니다.
다음의 예제에서 그룹 1을 사용하여 이 그룹에서 자유롭게 구독 및 구독해제 하도록 하였습니다.
Photon에 연결할 때 원하는 그룹에서 송신과 수신이 가능한지 확인하세요.
다음을 호출하여 이를 수행할 수 있습니다:
C#
PhotonNetwork.SetReceivingEnabled(1, true);
PhotonNetwork.SetSendingEnabled(1, true);
또한 인스턴스화된 게임 개체 (PhotonView 컴포넌트가 연결된 개체)가 그룹 변수를 원하는 그룹으로 설정했는지 확인하세요. 예를들어:
C#
public void Awake()
{
GetComponent<PhotonView>().group = 1;
}
대부분의 네트워크 트래픽을 특정 그룹으로 '이동한' 경우 브라우저의 JavaScript에서 호출되는 이 두 가지 함수를 계속 추가 할 수 있습니다.
예제에서는 'Subscribe' 와 'Unsubscribe' 로 이름을 부여했습니다. 두 함수는 다음과 같습니다:
C#
public void Subscribe()
{
GetComponent<PhotonView>().group = 1;
PhotonNetwork.SetReceivingEnabled(1, true);
PhotonNetwork.SetSendingEnabled(1, true);
}
public void Unsubscribe()
{
GetComponent<PhotonView>().group = 2;
PhotonNetwork.SetReceivingEnabled(1, false);
PhotonNetwork.SetSendingEnabled(1, false);
}
마지막 단계에서 할 일은 앞서 설명한 두 가지 함수를 호출 할 수 있도록 "index.html" 파일에 추가 할 JavaScript 스니펫을 조정하는 것입니다.
세 번째 방법 - 강제 업데이트와 연결 상태 유지
이 방법은 모든 수신 및 발신 메시지의 처리를 강제로 하기 때문에 이전의 두 방식과는 다릅니다.
따라서 기본 자바 스크립트 스니펫을 다음과 같이 조정해야 할 필요가 있습니다:
JavaScript
<script>
var isActive;
document.addEventListener('visibilitychange', function () {
if (document.visibilityState == "hidden") {
isActive = setInterval(function() { SendMessage("Receiver", "DoSomething"); }, 250);
} else {
clearInterval(isActive);
isActive = false;
}
});
</script>
이것은 현재 보이는 상태를 기반으로 타이머를 생성하고 파괴합니다.
이 타이머가 활성화되면 각 함수는 250 ms 또는 1초에 4회 호출됩니다.
SendMessage
함수의 매개 변수뿐만 아니라 요건에 맞게 간격을 조정할 수 있습니다.
이 업데이트가 있으므로 WebGL 프로젝트도 계속 조정할 수 있습니다.
그러므로 우리는 앞서 소개 한 타이머에서 호출 될 DoSomething
함수를 생성합니다.
이 함수는 다음과 같습니다:
C#
public void DoSomething()
{
if (!PhotonNetwork.connected || !PhotonNetwork.inRoom)
{
return;
}
PhotonNetwork.networkingPeer.DispatchIncomingCommands();
PhotonNetwork.networkingPeer.SendOutgoingCommands();
}
브라우저의 탭이 백그라운드에 있어도 네트워크의 메시지 흐름이 증가합니다.
이것이 좋은 아이디어 인것 같지만 이 방식 역시 큰 단점을 가지고 있습니다.
게임이 실제로 보이지 않을 때 캐릭터를 제어 할 수 없기 때문에 캐릭터의 변형과 관련된 사항은 변경되지 않습니다.
따라서 항상 동일한 정보를 다른 클라이언트에게 보냅니다.
이 의미는 중요한 콘텐츠가 없는 메시지 수가 증가 한다는 것 입니다.
그래서 이 모든 접근법은 모두 권장되지 않습니다.
네 번째 방법 - 세 번째 방법을 조정하여 계속 연결 유지
세 번째 방법을 권장하지 않을지라도 가장 마지막 방식에서 사용할 수 있습니다.
따라서 'DoSomething' 함수를 다음과 같이 변경 합니다:
C#
public void DoSomething()
{
PhotonNetwork.networkingPeer.SendAcksOnly();
}
이 연결을 유지하기 위해 단순히 서버에 인지를 보냅니다.
추가로 생성 된 간격에 관련된 게임 로직은 처리되지 않습니다.