실시간 통신 (Socket) - 포톤
클라이언트 - 서버 실시간으로 연결
한번 연결하면 계속 연결해놓은 상태로 유지
계속 왔다갔다 주기적으로 체크
양방향 통신
서버 개발자가 어떤걸 선택하는냐에 따라 다름
TCP - 데이터를 주고 받을 때 전달하는 신뢰 (유실되지 않겠끔) (더 느리지만 정확)
UDP - 전달하는 데이터가 유실 (속도가 더 빠름)
Http 통신 (웹통신)
클라이언트 -----> 서버 요청 / 응답
서버가 먼저 클라이언트한테 줄 수 없음
단방향 통신
REST API (주소 ex www.naver.com/login)
주소값을 통해서 통신을 하겠다
POST : 서버한테 데이터를 생성 (ex 유저정보 저장)
PUT : 서버한테 데이터를 업데이트 / 기존의 데이터를 수정
GET : 서버한테 데이터 요청 (ex 유저정보 주세요)
DELETE : 서버한테 데이터 삭제
서버들이 제작해놓은 url 을 주고 우리는 그 url을 사용하면 된다.
실무에서는 거의 POST GET만 사용 (서버에서 생성 수정을 해주는 식)
GET 실무.
테스트 가능한 사이
JSONPlaceholder - Free Fake REST API
{JSON} Placeholder Free fake API for testing and prototyping. Powered by JSON Server + LowDB. Tested with XV. Serving ~2 billion requests each month.
jsonplaceholder.typicode.com
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
//주소값
//https://jsonplaceholder.typicode.com
//예시
/*"postId": 1,
"id": 1,
"name": "id labore ex et quam laborum",
"email": "Eliseo@gardner.biz",
"body": "laudantium enim quasi est s\ntempiciendis et nam sapiente accusantium"*/
//통신관련 정보들은 한쪽에서 받기
[Serializable]
public class JsonList<T>
{
public List<T> data;
}
#region 테스트용
[Serializable]
public struct CommentInfo
{
public int postId;
public int id;
public string name;
public string email;
public string body;
}
//POST를 위한 임시값
[Serializable]
public struct SignUpInfo
{
public string userName;
public string brithDay;
public int age;
}
#endregion
public enum RequestType
{
GET,
POST,
PUT,
DELETE,
//이미지 다운로드
TEXTURE
}
//웹 통신하기 위한 정보를 가지고 있는 클래스
public class HttpInfo
{
public RequestType requestType;
public string url = "";
public string body; //json 형태로
//using System; 필요 딜리게이트 함수를 담을 수 있는 있는 변수
//어떤함수를 담을 것이지
public Action<DownloadHandler> onReceive;
//useDefaultUrl = 디폴트 true
public void Set(RequestType type, string u,
Action<DownloadHandler> callback, bool useDefaultUrl = true)
{
requestType = type;
//조건을 걸어준다.
if(useDefaultUrl) url = "https://jsonplaceholder.typicode.com";
url += u;
onReceive = callback;
}
}
//받아서 요청
public class HttpManager : MonoBehaviour
{
//public 삭제
static HttpManager instance;
//HttpManager return 하는 함수
//1.
public static HttpManager Get()
{
if(instance == null)
{
//게임오브젝트 생성 new
GameObject go = new GameObject("HttpStudy");
//만들어진 게임오브젝트에 HttpManager 컴포넌트 붙이자
go.AddComponent<HttpManager>();
}
return instance;
}
//2.
private void Awake()
{
if(instance == null)
{
instance = this;
//없으면 붙겠끔 하는 코드도 넣어주기
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
//서버에게 REST API 요청 (GET, POST, PUT, DELETE)
public void SendRequest(HttpInfo httpInfo)
{
StartCoroutine(CoSendRequest(httpInfo));
}
//코루틴으로 보내야됨.
//매개변수로 받아서 할 것임.
IEnumerator CoSendRequest(HttpInfo httpInfo)
{
//※로딩바 돌게
print("로딩바 도는 중");
//웹 통신을 위한 using UnityEngine.Networking; 필요
UnityWebRequest req = null;
switch(httpInfo.requestType)
{
case RequestType.GET:
//Get방식으로 req에 정보 셋팅
//req = UnityWebRequest.Get(주소값)
req = UnityWebRequest.Get(httpInfo.url);
break;
case RequestType.POST: //body, 헤더 필요
req = UnityWebRequest.PostWwwForm(httpInfo.url, httpInfo.body);
//byte [] 배열로 만들어야 한다 (using System.Text; 필요)
byte[] byteBody = Encoding.UTF8.GetBytes(httpInfo.body);
req.uploadHandler = new UploadHandlerRaw(byteBody);
//post는 헤더 추가해야함 (키 벨류) 여러개 등록할 수 있음 ++
req.SetRequestHeader("Content-Type","application/json");
break;
case RequestType.PUT:
req = UnityWebRequest.Put(httpInfo.url, "");
break;
case RequestType.DELETE:
req = UnityWebRequest.Delete(httpInfo.url);
break;
case RequestType.TEXTURE: //이미지다운로드
req = UnityWebRequestTexture.GetTexture(httpInfo.url);
break;
}
//서버에 요청을 보내고 응답이 올때까지 양보한다.
yield return req.SendWebRequest();
//응답도 Action을 통해서 할 것임.
//성공 or 실패
//만약에 응답이 성공했다면
if(req.result == UnityWebRequest.Result.Success)
{
//응답에 성공했을 때 req.downloandHandler.text 응답 받은 내용이 담겨져 있음
//print("네트워크 응답 : " + req.downloadHandler.text);
if(httpInfo.onReceive != null)
{
httpInfo.onReceive(req.downloadHandler);
}
}
//통신 실패
else
{
print("네트워크 에러 : " + req.error);
}
//※로딩바 끝나게
print("로딩바 끝남");
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
public Image downloadImage;
public void OnClickGet()
{
//todos
HttpInfo info = new HttpInfo();
info.Set(RequestType.GET, "/todos", OnReceiveGet);
//OnReceiveGet -> 람다식으로 무명함수 넣을 수 있음
/*info.Set(RequestType.GET, "/todos", (DownloadHandler downloadHandler) =>
{
print("OnReceiveGet" + downloadHandler.text);
});*/
//info의 정보를 요청을 보내자
HttpManager.Get().SendRequest(info);
}
//using UnityEngine.Networking; 필요
void OnReceiveGet(DownloadHandler downloadHandler)
{
print("OnReceiveGet" + downloadHandler.text);
}
public List<CommentInfo> comments;
public void OnClickComment()
{
//todos
HttpInfo info = new HttpInfo();
//info.Set(RequestType.GET, "/todos", OnReceiveGet);
//OnReceiveGet -> 람다식으로 무명함수 넣을 수 있음
info.Set(RequestType.GET, "/comments", (DownloadHandler downloadHandler) =>
{
print("코멘트 리스트" + downloadHandler.text);
//Json 데이터로 가공
//"{\ 문자열안에 스트링으로 인식함
string jsonData = "{\"data\" : " + downloadHandler.text + "}";
JsonList<CommentInfo> commentList = JsonUtility.FromJson<JsonList<CommentInfo>>(jsonData);
comments = commentList.data;
});
//info의 정보를 요청을 보내자
HttpManager.Get().SendRequest(info);
}
public void PostTest()
{
HttpInfo info = new HttpInfo();
info.Set(RequestType.POST, "/sign_up", (DownloadHandler downloadHandeler) => {
//Post 데이터 전송했을 때 서버로부터 응답 옵니다.
});
SignUpInfo signUpInfo = new SignUpInfo();
signUpInfo.userName = "김현진";
signUpInfo.age = 25;
signUpInfo.brithDay = "830410";
//Json 데이터를 넣겠다.
info.body = JsonUtility.ToJson(signUpInfo);
HttpManager.Get().SendRequest(info);
}
public void OnClickDownloadImage()
{
//https://via.placeholder.com/150/92c952
HttpInfo info = new HttpInfo();
//기본 URL을 쓸 필요가 없다.
info.Set(
RequestType.TEXTURE,
"https://item.kakaocdn.net/do/c838c164801d148d4fe09b83adada4c88f324a0b9c48f77dbce3a43bd11ce785",
OnCompleteDownloadTexture, false);
//info의 정보를 요청을 보내자
HttpManager.Get().SendRequest(info);
}
//다운로드 된 이미지
//텍스처는 Json 형태가 아님 색상정보
void OnCompleteDownloadTexture(DownloadHandler downloadHandler)
{
//다운로드된 Image 데이터를 Sprite 로 만든다. //형변환
//Texture2D -> Sprite
Texture2D texture = ((DownloadHandlerTexture)downloadHandler).texture;
//새로운 사각형
downloadImage.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
}
}
'유니티' 카테고리의 다른 글
Firebase (1) | 2023.08.29 |
---|---|
[유니티] 싱글톤만들기 (0) | 2023.08.26 |
JSON (JavaScript Object Notation) (1) | 2023.08.23 |
[유니티] 파일저장 (0) | 2023.08.23 |
[유니티] Joints (0) | 2023.08.17 |