Photon Socket TCP vs UDP
- HTTP통신 -> 단방향 통신
- Socket통신 (TCP,UDP) -> 양방향 통신 / 서버와 연결이 지속 됨
Client <-> Server 서로 데이터를 주고 받음
실시간 통신(채팅 , 온라인 게임)
1) TCP (Transmission control protocol)
- 데이터의 안정성을 보장 / 데이터 검증 O
- UDP 보다 속도는 조금 느리다
2) UDP (User Datagram protocol)
- 데이터의 손실이 발생할 수 있다 => 안정성이 TCP보다 낮음
- TCP보다 속도가 빠르다 (데이터 정확성 검사X)
우리는 연결하는 방법만 알면 된다!
통신 방법 (흐름도)
< Server >
: 소켓 생성 → 소켓주소 할당(Binding) → 연결 대기(Listen) → 연결 승인→ 데이터 송수신
→ close
< Client >
: 소켓 생성 → 연결 요청→ 연결 대기(Listen) → 연결 승인→ 데이터 송수신
→ close
Photon 구조
- photon Engine
https://www.photonengine.com/ko-KR/Photon 회원가입 진행
포톤서버만들기
- Photon TypePun / Realtime(Pun의 업그레이드 버전) Chat / Voice(음성채팅도 가능)- Name : XR_ B
App ID 사용
- Asset Store
PUN2 - FREE 다운로드
- Photon 엔진의 서버 구조
1) Name Server
AppID / GameVersion / 지역 이 같은 애들끼리 같은 곳에 접속이 가능하도록 분류
2) Master Server
로비접속 가능
로비 개념 = 채널 (ex) 카트라이더 접속-> 방목록 / 방 생성 가능 / 방 입장 가능
3) Game Server
각 방에서 진행되는 서버
프로토때는 Game Server에 집중!
Photon 초기 셋팅
- 포톤 설정해주기
Assets > Photon > PhotonUnityNetworking > Resources > PhotonServerSettings
> App Id PUN / App Version / Fixed Region
- Scene 3개 생성
ConnectionScene
1) ConnectionScene
ConnectionManager - Script 생성
ConnectionManager - Create Empty 생성
* Photon에 대한 기능을 쓰기 위해
using Photon.Pun
using Photon.Realtime;
* Photon에서 만들어 준 클래스로 상속을 받아야 함
MonoBehaviourPunCallbacks (MonoBehaviour 상속 받음)
* C#은 다중상속이 안되지만 interface를 통해 여러개를 상속시킬 수 있는 형태를 가질 수 있음
Photon Photon Callback interface - 함수들을 호출해준다 (함수 정의 - 가상함수로 되어있음 / 구현은 안되있음)
대표적인 interface
IConnectionCallbacks : 연결 관리
ILobbyCallbacks : Lobby와 관련
IInRoomCallbacks : Room과 관련
요청 -> 응답 받고 진행이 됨!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Photon.Pun;
using Photon.Realtime;
public class ConnectionManager : MonoBehaviourPunCallbacks
{
void Start()
{
// 1.
// 서버 접속 -> Photon 클래스들을 사용해야 함
// App Id PUN / App Version / Fixed Region 참고해서 서버에 접속
// Name Server에 접속 -> MasterServer 접속 (서버 접속 요청)
PhotonNetwork.ConnectUsingSettings();
}
// (응답)
// 서버에 요청하고 성공하게 되면 함수 호출
// 마스터 서버 접속성공 시 호출(Lobby에 진입할 수 없는 상태)
public override void OnConnected()
{
base.OnConnected();
//현재 진행되고 있는 함수의 이름 print = print("OnConnected");
print(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
// 마스터 서버 접속성공 시 호출(Lobby에 진입 할 수 있는 상태)
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
print(System.Reflection.MethodBase.GetCurrentMethod().Name);
// 2.
// 닉네임 설정 Test (나중에 직접 닉네임을 써서 변경)
PhotonNetwork.NickName = "김현진_" + Random.Range(1, 10000);
// 채널을 다르게 생성
// 기본 로비 진입 (서버 요청)
PhotonNetwork.JoinLobby();
// 특정 로비 진입 // 매개변수 차이 -> 함수의 오버로딩
//PhotonNetwork.JoinLobby(new TypedLobby("들어가고 싶은 로비 이름",LobbyType.Default));
}
// (응답)
// 로비 진입 성공시 호출
public override void OnJoinedLobby()
{
base.OnJoinedLobby();
print(System.Reflection.MethodBase.GetCurrentMethod().Name);
//LobbyScene으로 이동
SceneManager.LoadScene("LobbyScene");
}
알아야 할 점!
오버로딩(overloading)은 이름은 같지만 시그니처(파라미터 수, 타입) 데는 다른 메소드를 중복으로 선언하는 것을 의미하고, 오버라이딩(overriding)은 부모 클래스의 메소드의 동작 방법을 변경(재정의)하여 우선적으로 사용하는 것이다.
1 Master Server까지 접속
- PhotonNetwork.ConnectUsingSettings();
- override OnConnected()
- override OnConnectedToMaster()
2 Lobby 진입
- 닉네임 설정 PhotonNetwork.NickName = "김현진_" + Random.Range(1, 10000);
- 채널 다르게 생성하고 싶다면
PhotonNetwork.JoinLobby();
PhotonNetwork.JoinLobby(new TypedLobby("들어가고 싶은 로비 이름",LobbyType.Default));
- override OnJoinedLobby()
- 씬 이동을 위해 using UnityEngine.SceneManagement 추가
SceneManager.LoadScene("LobbyScene");
- LobbyScene 추가 / 빌드 셋팅
LobbyScene
2) LobbyScene
LobbyManager - Script 생성
LobbyManager - Create Empty 생성
* Photon에 대한 기능을 쓰기 위해
using Photon.Pun
using Photon.Realtime;
* Photon에서 만들어 준 클래스로 상속을 받아야 함
MonoBehaviourPunCallbacks (MonoBehaviour 상속 받음)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.SceneManagement;
public class LobbyManager : MonoBehaviourPunCallbacks
{
// Start is called before the first frame update
void Start()
{
// 1.
// 방생성 호출
CreateRoom();
}
// Update is called once per frame
void Update()
{
}
// 방생성 함수
public void CreateRoom()
{
// 방정보 셋팅 RoomOptions 클래스 이용
RoomOptions roomOptions = new RoomOptions();
// 최대 인원 설정 //byte number = 255
// 셋팅을 안하면 0 / 최대인원 (0명이면 최대인원 = 255)
roomOptions.MaxPlayers = 10;
// 룸 목록에 보이냐? 보이지 않는냐?
roomOptions.IsVisible = true; //보임
// 방을 만든다 -> 방 제목
PhotonNetwork.CreateRoom("XR_LHS", roomOptions, TypedLobby.Default);
}
// 방 생성 완료
public override void OnCreatedRoom()
{
base.OnCreatedRoom();
print(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
// 똑같은 이름으로 만들어지면 방 생성 실패
public override void OnCreateRoomFailed(short returnCode, string message)
{
base.OnCreateRoomFailed(returnCode, message);
// 나중에 팝업 처리 -> 경고 문구
print("OnCreateRoomFailed, " + returnCode + "," + message);
// 생성 실패 시 JoinRoom을 실행하겠다
JoinRoom();
}
// 2.
// 방생성자는 자동으로 입장이 된다
// 방 참가 요청(요청)
public void JoinRoom()
{
PhotonNetwork.JoinRoom("XR_LHS");
//PhotonNetwork.JoinOrCreateRoom :-> 방 옵션 셋팅을 해줘야 한다
}
//(응답)
// 방 참가가 완료 되었을 때 호출 되는 함수
public override void OnJoinedRoom()
{
base.OnJoinedRoom();
print(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
// 방 참가가 실패 되었을 때 호출 되는 함수
public override void OnJoinRoomFailed(short returnCode, string message)
{
base.OnJoinRoomFailed(returnCode, message);
print("OnJoinRoomFailed, " + returnCode + "," + message);
}
}
1 방 생성
- CreateRoom(); - 방 정보 셋팅
- PhotonNetwork.CreateRoom("방 이름" , roomOptions, TypedLobby.Default);
- override OnCreatedRoom()
- override OnCreateRoomFailed()
에러 발생 시켜보기
(빌드 셋팅 : Player Settings > Resolution and Presentation > Windowed (800 / 600))
Asset Store > Debug (콘솔창에 나오는 내용들을 UI로 표시해주는 에셋)
Assets > Plugins > IngameDebugConsole > Prefabs
2 방 입장
- JoinRoom();
- JoinRoom : 선택한 방에 parameter값을 할당해 방을들어가겠다. (이름지정)
실패했을때 함수 > OnJoinRoomFailed
- JoinOrCreateRoom : 방 이름을 설정해서 들어갈 때, 해당 이름으로 된 방이 없으면 방을 생성해 입장함
- JoinRandomRoom : 랜덤한 방 입장 (이름설정없음)
- JoinRandomOrCreateRoom : 랜덤한 방에 들어가려고 할때, 조건에 맞는 방이 없다면 방 생성 후 입장
실패했을때 함수 > OnJoinRandomFailed
- override OnJoinedRoom()
- override OnJoinRoomFailed()
CreateRoom 실패 / JoinRoom 실패 시
CreateRoom 실패 / JoinRoom 성공