Version : Unity 2021.3.5f1
MDN
The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.
웹 사이트와 프로그레시브 웹 앱 모두에 대한 HTML, CSS 및 API를 포함한 개방형 웹 기술에 대한 정보를 제공하는 사이트
https://developer.mozilla.org/ko/docs/Web/JavaScript

EXPRESS
https://ninjaggobugi.tistory.com/9 <- 자세한 설명
Express란?
Express는 웹 및 모바일 애플리케이션을 위한 일련의 강력한 기능을 제공하는 간결하고 유연한 Node.js 웹 애플리케이션 프레임 워크
Node.js는 Chrome의 V8엔진을 이용하여 javascript로 브라우저가 아니라 서버를 구축하고, 서버에서 JavaScript가 작동되도록 해주는 런타임 환경(플랫폼)
Express는 이런 Nodejs의 원칙과 방법을 이용하여 웹애플리케이션을 만들기 위한 프레임워크이다.

NPM
npm(node package manager)은 자바스크립트 패키지 매니저이다. Node.js에서 사용할 수 있는 모듈들을 패키지화하여 모아둔 저장소 역할과 패키지 설치 및 관리를 위한 CLI(Command line interface)를 제공한다.
자신이 작성한 패키지를 공개할 수도 있고 필요한 패키지를 검색하여 재사용할 수도 있다.

Mysql
Mysql용 node.js 드라이버
https://www.npmjs.com/package/mysql

Mysql2
async/await을 사용하기 위해선 mysql2를 설치 해야 한다.
콜백 방식이 싫다면 사용하자
https://www.npmjs.com/package/mysql2

npm init 해주기
https://www.dailysmarty.com/posts/npm-init-y-explanation

$npm init -y
npm(Node Package Manager) 에서 express설치
$ npm install express
npm(Node Package Manager) 에서 mysql2 설치
npm install --save mysql2
postman 다운로드
Postman은 개발한 API를 테스트하고, 테스트 결과를 공유하여 API 개발의 생산성을 높여주는 플랫폼




const express = require(`express`); const app = express(); app.get(`/`, function (req, res) { res.send(`hello World`); }) app.listen(포트);
공유기 포트 포워딩

포스트맨 확인



const express = require(`express`); const app = express(); const port = ; app.get(`/`, function (req, res) { res.send(`hello World`); }); app.listen(port, () => { console.log(`Rest API SERVER 실행됨 port : ${port}`); });
GET POST 차이점
https://noahlogs.tistory.com/35 <- 자세한 설명
GET 이란?
GET 은 클라이언트에서 서버로 어떠한 리소스로부터 정보를 요청하기 위해 사용되는 메서드이다.
예를 들면 게시판의 게시물을 조회할 때 쓸 수 있다.
GET을 통한 요청은 URL 주소 끝에 파라미터로 포함되어 전송되며, 이 부분을 쿼리 스트링 (query string)이라고 부른다.
방식은 URL 끝에 “? “를 붙이고 그다음 변수명 1=값 1&변수명 2=값 2… 형식으로 이어 붙이면 된다.
예를 들어 다음과 같은 방식이다.
www.example.com/show?name1=value1&name2=value2
서버에서는 name1과 name2라는 파라미터 명으로 각각 value1과 value2의 파라미터 값을 전달받을 수 있다.
GET의 특징
- GET 요청은 캐시가 가능하다. : GET을 통해 서버에 리소스를 요청할 때 웹 캐시가 요청을 가로채 서버로부터 리소스를 다시 다운로드하는 대신 리소스의 복사본을 반환한다. HTTP 헤더에서 cache-control 헤더를 통해 캐시 옵션을 지정할 수 있다.
- GET 요청은 브라우저 히스토리에 남는다.
- GET 요청은 북마크 될 수 있다.
- GET 요청은 길이 제한이 있다. : GET 요청의 길이 제한은 표준이 따로 있는건 아니고 브라우저마다 제한이 다르다고 한다.
- GET 요청은 중요한 정보를 다루면 안된다. ( 보안 ) : GET 요청은 파라미터에 다 노출되어 버리기 때문에 최소한의 보안 의식이라 생각하자.
- GET은 데이터를 요청할때만 사용 된다.
POST 란?
POST는 클라이언트에서 서버로 리소스를 생성하거나 업데이트하기 위해 데이터를 보낼 때 사용되는 메서드다. 예를 들면 게시판에 게시글을 작성하는 작업 등을 할 때 사용할 된다.
POST는 전송할 데이터를 HTTP 메시지 body 부분에 담아서 서버로 보낸다. ( body 의 타입은 Content-Type 헤더에 따라 결정된다.)
GET에서 URL의 파라미터로 보냈던 name1=value1&name2=value2 가 body에 담겨 보내진다 생각하면 된다.
POST로 데이터를 전송할 때 길이 제한이 따로 없어 용량이 큰 데이터를 보낼 때 사용하거나 GET처럼 데이터가 외부적으로 드러나는 건 아니라서 보안이 필요한 부분에 많이 사용된다.
( 하지만 데이터를 암호화하지 않으면 body의 데이터도 결국 볼 수 있는 건 똑같다. )
POST를 통한 데이터 전송은 보통 HTML form을 통해 서버로 전송된다.
POST의 특징
- POST 요청은 캐시되지 않는다.
- POST 요청은 브라우저 히스토리에 남지 않는다.
- POST 요청은 북마크 되지 않는다.
- POST 요청은 데이터 길이에 제한이 없다.
GET 과 POST 의 차이점
GET과 POST의 특징만 보아도 차이가 나긴하지만 추가적으로 차이점을 정리해보면 다음과 같다.
- 사용목적 : GET은 서버의 리소스에서 데이터를 요청할 때, POST는 서버의 리소스를 새로 생성하거나 업데이트할 때 사용한다.DB로 따지면 GET은 SELECT 에 가깝고, POST는 Create 에 가깝다고 보면 된다.
- 요청에 body 유무 : GET 은 URL 파라미터에 요청하는 데이터를 담아 보내기 때문에 HTTP 메시지에 body가 없다. POST 는 body 에 데이터를 담아 보내기 때문에 당연히 HTTP 메시지에 body가 존재한다.
- 멱등성 (idempotent) : GET 요청은 멱등이며, POST는 멱등이 아니다.
멱등이란?
멱등의 사전적 정의는 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다.
GET은 리소스를 조회한다는 점에서 여러 번 요청하더라도 응답이 똑같을 것 이다. 반대로 POST는 리소스를 새로 생성하거나 업데이트할 때 사용되기 때문에 멱등이 아니라고 볼 수 있다. (POST 요청이 발생하면 서버가 변경될 수 있다.)
GET과 POST는 이런 차이들이 있기 때문에 사용하려는 목적에 맞는 확인한 후에 사용해야한다.
GET과 POST 이외에도 PUT , DELETE 등을 적절히 사용하는게 좋은데 예를들어 봇의 경우에 사이트를 돌아다니면서 GET 요청을 날린다. 이럴 때 DELETE 등을 GET으로 처리하면 봇에 의해 서버에 있는 리소스들이 삭제 되는 상황이 일어 날수 있다! 항상 기술을 사용할 때 왜 를 잊지말자.

citysRouter.js
const express = require(`express`); const citysDBC = require(`./citysDBC`); const router = express.Router(); router.get('/getCitys', async (req, res)=>{ let res_get_citys = { status : 500, citys : [] }; try{ const rows = await citysDBC.getCitys(); res_get_citys.status = 200; if(rows.length > 0){ rows.forEach((city)=>{ res_get_citys.citys.push(city); }); }else{ console.log('도시 없음'); } }catch(error) { console.log(error.message); }finally { //응답 res.json(res_get_citys); } }); module.exports = router;
app.js
const express = require(`express`); const citysRouter = require('./citysRouter'); const app = express(); const port = ; app.use(express.json()); // json app.use('/city', citysRouter); app.get(`/`, function (req, res) { res.send(`<h2>Welcome to REST API SERVER. </h2>`); }); app.listen(port, () => { console.log(`Rest API SERVER 실행됨 port : ${port}`); });
citysDBC.js
// get the client const mysql = require('mysql2'); // Create the connection pool. The pool-specific settings are the defaults const pool = mysql.createPool({ host: 'localhost', user: '', password: '', database: '', port: , waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); const getCitys = async ()=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query('SELECT * FROM city;'); return rows; }; module.exports = { getCitys };
완료




USER 등록 및 검색
usersDBC.js
// get the client const mysql = require('mysql2'); const pool = mysql.createPool({ host: '', user: '', password: '', database: 'test_schema', port: , waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); const signup = async (values)=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query('insert into users (user_uid, nickname) values (?, ?)', values); //console.log(rows); return rows; }; const getUsers = async ()=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query('select * from users;'); console.log(rows); return rows; }; module.exports = { getUsers, signup };
usersRouter.js
const express = require(`express`); const userDBC = require(`./usersDBC`); const router = express.Router(); router.post('/signup', async(req, res)=>{ const res_signup = { status_code : 500 }; try{ const {user_uid, nickname} = req.body; const rows = await userDBC.signup([user_uid, nickname]); if(rows.affectedRows > 0){ // 적용됨 res_signup.status_code = 200; }else{ // 적용 안됨 res_signup.status_code = 201; } }catch(err) { //에러 console.log(err.message); }finally{ res.json(res_signup); } }); router.get('/getUsers', async (req, res)=>{ let res_get_users = { status_code : 500, users : [] }; try{ const rows = await userDBC.getUsers(); res_get_users.status_code = 200; if(rows.length > 0){ rows.forEach((user)=>{ res_get_users.users.push({ nickname : user.nickname }); }); }else{ console.log('사용자 없음'); } }catch(error) { console.log(error.message); }finally { //응답 res.json(res_get_users); } }); module.exports = router;
app.js
const express = require(`express`); const citysRouter = require('./citysRouter'); const usersRouter = require('./usersRouter'); const app = express(); const port = ; app.use(express.json()); // json app.use('/city', citysRouter); app.use('/user', usersRouter); app.get(`/`, function (req, res) { res.send(`<h2>Welcome to REST API SERVER. </h2>`); }); app.listen(port, () => { console.log(`Rest API SERVER 실행됨 port : ${port}`); });




cd .. 상위 디렉토리
cd – 뒤로가기
cd 폴더명 해당 디렉토리로
dir 위치의 파일 확인
mkdir 폴더명
pushd <-UNC 경로 지원 안할때
node js
netstat -a 사용중인 포트 보기
netstat findstr: 포트 번호
(혹은 netstat -an | findstr:”포트넘버”) 를 통해 특정한 포트넘버를 직접 찾을 수도 있다.
*-an 은 -a와 -n 을 합친 명령어로서 n은 숫자를 의미한다.
*findstr 은 특정 문자를 포함한 문자열을 찾는다는 뜻이다.)
ps -aef | grep node 사용중인 노드 보기
Taskkill /IM node.exe /F 를 입력해
kill node
killall node
Node.js 를 통해 실행중인 모든 서버를 종료할 수 있다.
taskkill /f /pid (종료할 pid) 를 입력하여 특정 pid를 가진 연결을 종료시킨다.
(pid는 맨 오른쪽에 있는 숫자가 pid이다.)
- pid 란 process ID 를 뜻한다.
연습용 프로토콜 문서

usersRouter.js
const express = require(`express`); const userDBC = require(`./usersDBC`); const router = express.Router(); router.post('/signUp', async(req, res)=>{ const res_signup = { status_code : 500 }; try{ const {user_uid, nickname} = req.body; const rows = await userDBC.signUp([user_uid, nickname]); if(rows.affectedRows > 0){ //적용됨 res_signup.status_code = 200; }else{ //적용안됨 res_signup.status_code = 201; } }catch(err) { //에러 console.log(err.message); }finally{ res.json(res_signup); } }); router.get('/getUsers', async (req, res)=>{ let res_get_users = { status_code : 500, users : [] }; try{ const rows = await userDBC.getUsers(); res_get_users.status_code = 200; if(rows.length > 0){ rows.forEach((user)=>{ res_get_users.users.push({ nickname : user.nickname }); }); }else{ console.log('사용자 없음'); } }catch(error) { console.log(error.message); }finally { //응답 res.json(res_get_users); } }); router.post('/nasSignUp', async(req, res)=>{ const res_signup = { status_Code : 500 }; try{ //console.log(req.body); const {user_uid, nickname} = req.body; const row = await userDBC.nasSignUp([user_uid, nickname]); if(row.length > 0) { res_signup.status_Code = row[0]; } }catch(err) { //에러 console.log(err.message); }finally{ res.json(res_signup.status_Code); } }); router.post('/nasGetUser', async(req, res)=>{ const res_getuser = { statusCode : 500, nickname : "" }; try{ const {user_uid} = req.body; const row = await userDBC.nasGetUser([user_uid]); const row2 = await userDBC.nasGetUserNick([user_uid]); if(row.length > 0) { res_getuser.statusCode = row[0].statusCode; res_getuser.nickname = row2[0].nickname; } console.log(row); } catch(err) { //에러 console.log(err.message); } finally{ res.json(res_getuser); } }); router.post('/nasSignOut', async(req, res)=>{ const res_signup = { status_Code : 500 }; try{ const {user_uid} = req.body; const row = await userDBC.nasSignOut([user_uid]); if(row.length > 0) { res_signup.status_Code = row[0]; } }catch(err) { //에러 console.log(err.message); }finally{ res.json(res_signup.status_Code); } }); module.exports = router;
usersDBC.js
// get the client const mysql = require('mysql2'); const pool = mysql.createPool({ host: ' user: ' password: ' database: ' port: waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); const signUp = async (values)=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query('insert into users (user_uid, nickname) values (?, ?)', values); //console.log(rows); return rows; }; const getUsers = async ()=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query('select * from users;'); console.log(rows); return rows; }; const signOut = async () => { const promisePool = pool.promise(); const [rows] = await promisePool.query(``) }; const nasSignUp = async ([user_uid, nickname])=>{ const promisePool = pool.promise(); //console.log(user_uid); //console.log(nickname); const [rows] = await promisePool.query(`SELECT FNC_sign_Up('${user_uid}','${nickname}') AS statusCode;`); //console.log(rows); return rows; }; const nasGetUser = async ([user_uid])=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query(`SELECT FNC_getUser_statusCode('${user_uid}') AS statusCode;`); return rows; }; const nasGetUserNick = async ([user_uid])=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query(`SELECT FNC_getUser_nickName('${user_uid}') AS nickname;`); return rows; }; const nasSignOut = async ([user_uid])=>{ const promisePool = pool.promise(); const [rows] = await promisePool.query(`SELECT FNC_signOut('${user_uid}') AS statusCode;`); return rows; }; module.exports = { getUsers, signUp, signOut, nasSignUp, nasGetUser, nasGetUserNick, nasSignOut };
app.js
const express = require(`express`); const citysRouter = require('./citysRouter'); const usersRouter = require('./usersRouter'); const app = express(); const port = ; app.use(express.json()); // json app.use('/city', citysRouter); app.use('/user', usersRouter); app.get(`/`, function (req, res) { res.send(`<h2>Welcome to REST API SERVER. </h2>`); }); app.listen(port, () => { console.log(`Rest API SERVER 실행됨 port : ${port}`); });
Query
USE test_schema; SELECT * FROM users; DELETE FROM users WHERE user_uid = '445a6a0a-577f-4ae4-b6f3-6f1301380edf'; ## 유저를 등록 delimiter // CREATE FUNCTION FNC_sign_Up($user_uid varchar(45), $nickName varchar(45)) RETURNS INT BEGIN SET @user_uid_duplicate_check = 0; -- 유저 uid로 검색하여 중복 체크 SET @nickname_duplicate_check = 0; -- 닉네임 중복 체크 SET @statusCode = 200; -- 기본으로 200 -- 200 유저 등록 완료 -- 201 이미 등록된 유저 -- 202 중복 닉네임 -- 500 서버 에러 select count(*) into @user_uid_duplicate_check from users where user_uid = $user_uid; select count(*) into @nickname_duplicate_check from users where nickName = $nickName; CASE WHEN @user_uid_duplicate_check > 0 THEN set @statusCode = 201; -- 이미 등록된 유저 WHEN @nickname_duplicate_check > 0 THEN set @statusCode = 202; -- 이미 등록된 닉네임 ELSE INSERT INTO users (user_uid, nickname) values ($user_uid, $nickName); END case; return @statusCode; -- 처리 결과를 반환함 END // delimiter ; SHOW function status; DROP FUNCTION FNC_sign_Up; SELECT FNC_sign_Up('13978557c-2810-4cbf-bd4b-1d4decac45d3', '최토리') AS status_Code; SELECT FNC_sign_Up('445a6a0a-577f-4ae4-b6f3-6f1301380edf', '토리') AS status_Code; ## 유저를 검색 delimiter // CREATE FUNCTION FNC_getUser_statusCode($user_uid varchar(45)) RETURNS INT BEGIN SET @user_uid_duplicate_check = 0; -- 유저 uid로 검색하여 체크 SET @statusCode = 500; -- 기본으로 500 -- 200 유저 검색 완료 -- 201 등록 되지 않은 유저 -- 500 서버 에러 select count(*) into @user_uid_duplicate_check from users where user_uid = $user_uid; CASE WHEN @user_uid_duplicate_check = 0 THEN set @statusCode = 201; -- 등록 되지 않은 유저 WHEN @user_uid_duplicate_check = 1 THEN set @statusCode = 200; -- 등록된 유저 END case; return @statusCode; -- 처리 결과를 반환함 END // delimiter ; SELECT FNC_getUser_statusCode('13978557c-2810-4cbf-bd4b-1d4decac45d3') AS statusCode; SHOW function status; DROP FUNCTION FNC_getUser_statusCode; ## UID로 유저를 검색 delimiter // CREATE FUNCTION FNC_getUser_nickName($user_uid varchar(45)) RETURNS varchar(45) BEGIN declare tnickname varchar(45); select nickname into tnickname from users where user_uid = $user_uid; return tnickname; END // delimiter ; SELECT FNC_getUser_nickName('445a6a0a-577f-4ae4-b6f3-6f1301380edf') AS nickname; DROP FUNCTION FNC_getUser_nickName; ## 유저를 삭제 delimiter // CREATE FUNCTION FNC_signOut($user_uid varchar(45)) RETURNS INT BEGIN SET @user_uid_duplicate_check = 0; -- 유저 uid로 검색하여 체크 SET @statusCode = 500; -- 기본으로 500 -- 200 유저 탈퇴 완료 -- 201 등록 되지 않은 유저 -- 500 서버 에러 select count(*) into @user_uid_duplicate_check from users where user_uid = $user_uid; CASE WHEN @user_uid_duplicate_check = 0 THEN set @statusCode = 201; -- 등록 되지 않은 유저 WHEN @user_uid_duplicate_check = 1 THEN set @statusCode = 200; DELETE FROM users WHERE user_uid = $user_uid; -- 등록된 유저 END case; return @statusCode; -- 처리 결과를 반환함 END // delimiter ; DROP FUNCTION FNC_signOut; SELECT FNC_signOut('13978557c-2810-4cbf-bd4b-1d4decac45d3') AS statusCode;
이제 간단하게 클라이언트(유니티)와 상호작용을 해보자
일단 계정을 등록하고 그 결과를 받아오는 부분을 해보겠습니다.


일단 유저의 Uid는 개인적으로 생성한 것 입니다.
https://www.uuidgenerator.net/ <- UUID 생성 사이트
닉네임을 입력하고 등록하면 유저의 Uid/nickname이 중복인지 확인을 하고 해당 결과를 보내줍니다.
테이블의 상태

서버 OFF 상태


서버 ON 상태 – 유저 등록 성공

데이터가 잘 들어온 것을 확인 할 수 있다.

SignUP 작업만 완료된 코드
HTTPManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using Newtonsoft.Json; using System.Text; public class HTTPManager : MonoBehaviour { public static HTTPManager instance; public string host = ""; public int port = ; public System.Action<int> getSignUpResult; // 싱글톤으로 만들어주자 private void Awake() { HTTPManager.instance = this; } private void OnDestroy() { HTTPManager.instance = null; } // uri => /user/signup public void RequestSignup(string uri, Packets.req_nasSignUp packet) { StartCoroutine(this.RequestSignupImpl(uri, packet)); } private IEnumerator RequestSignupImpl(string uri, Packets.req_nasSignUp packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); Debug.Log(url); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_signup = JsonConvert.DeserializeObject<Packets.res_nasSignUp>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}", res_signup.statusCode); this.getSignUpResult(res_signup.statusCode); } else { this.getSignUpResult(500); Debug.LogFormat("에러"); } www.Dispose(); } }
Packets.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Packets { /* 유저 등록(/users/nasSignUp) statusCode 200 유저 등록 완료 201 이미 등록된 유저 202 중복 닉네임 500 서버 에러 */ public class req_nasSignUp { public string user_uid; public string nickname; } public class res_nasSignUp { public int statusCode; } /* 유저 검색 (/users/nasGetUser) statusCode 200 유저 검색 완료 201 등록 되지 않는 유저 500 서버 에러 */ public class req_nasGetUser { public string user_uid; } public class res_nasGetUser { public int status_code; public string users; } }
RestTestMain.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class RestTestMain : MonoBehaviour { public TMP_Text tmp_User_Uid; private string user_Uid; public TMP_InputField userNickName_IF; private string user_NickName; public Button sighUpBtn; public TMP_Text result_Text; void Start() { this.user_Uid = tmp_User_Uid.text; HTTPManager.instance.getSignUpResult = (packet) => { Debug.LogFormat("HTTPManager.instance.getSignUpResult : {0}", packet) ; switch (packet) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 등록 완료", packet); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 이미 등록된 유저입니다.", packet); break; case 202: this.result_Text.text = string.Format("status_code : {0}, 중복된 닉네임 입니다.", packet); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet); break; } }; this.sighUpBtn.onClick.AddListener(() => { this.user_NickName = this.userNickName_IF.text; Debug.LogFormat("TMP_InputField : {0}", this.user_NickName); if (string.IsNullOrEmpty(this.user_NickName) && string.IsNullOrEmpty(this.user_Uid)) { Debug.Log("닉네임을 입력해주세요."); } else { Debug.LogFormat("{0}, {1}", this.user_Uid, this.user_NickName); var packet = new Packets.req_nasSignUp() { user_uid = this.user_Uid, nickname = this.user_NickName }; HTTPManager.instance.RequestSignup("/user/nasSignUp",packet); } }); } }
유니티에서 메모리 누수 오류가 뜨면 하단부를 추가하자

다음은 Uid로 유저를 검색해보자
항상 느끼는 거지만 코드를 작성하는 것보다 환경 구성하는 게 제일 화가 난다.




서버 OFF

HTTPManager.cs – GetUser 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using Newtonsoft.Json; using System.Text; public class HTTPManager : MonoBehaviour { public static HTTPManager instance; public string host = ""; public int port = ; public System.Action<int> getSignUpResult; public System.Action<Packets.res_nasGetUser> getGetUserResult; // 싱글톤으로 만들어주자 private void Awake() { HTTPManager.instance = this; } private void OnDestroy() { HTTPManager.instance = null; } // uri => /user/signup public void RequestSignup(string uri, Packets.req_nasSignUp packet) { StartCoroutine(this.RequestSignupImpl(uri, packet)); } private IEnumerator RequestSignupImpl(string uri, Packets.req_nasSignUp packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); Debug.Log(url); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_signup = JsonConvert.DeserializeObject<Packets.res_nasSignUp>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}", res_signup.statusCode); this.getSignUpResult(res_signup.statusCode); } else { this.getSignUpResult(500); Debug.LogFormat("에러"); } www.Dispose(); } public void RequestGetUser(string uri, Packets.req_nasGetUser packet) { StartCoroutine(this.RequestGetUserImpl(uri, packet)); } private IEnumerator RequestGetUserImpl(string uri, Packets.req_nasGetUser packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); Debug.Log(url); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_getuser = JsonConvert.DeserializeObject<Packets.res_nasGetUser>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}, nickName : {1}", res_getuser.statusCode, res_getuser.nickname); this.getGetUserResult(res_getuser); } else { Packets.res_nasGetUser res_getuser = new Packets.res_nasGetUser(); res_getuser.statusCode = 500; res_getuser.nickname = ""; this.getGetUserResult(res_getuser); Debug.LogFormat("에러"); } www.Dispose(); } }
Packets.cs – GetUser 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Packets { /* 유저 등록(/users/nasSignUp) statusCode 200 유저 등록 완료 201 이미 등록된 유저 202 중복 닉네임 500 서버 에러 */ public class req_nasSignUp { public string user_uid; public string nickname; } public class res_nasSignUp { public int statusCode; } /* 유저 검색 (/users/nasGetUser) statusCode 200 유저 검색 완료 201 등록 되지 않는 유저 500 서버 에러 */ public class req_nasGetUser { public string user_uid; } public class res_nasGetUser { public int statusCode; public string nickname; } }
RestTestMain.cs – GetUser 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class RestTestMain : MonoBehaviour { public Button SignUpTabBtn; public Button GetUserTabBtn; public GameObject SignUpGO; public GameObject GetUserGO; public TMP_Text tmp_User_Uid; private string user_Uid; public TMP_InputField userNickName_IF; private string user_NickName; public TMP_InputField UserUid_IF; public Button sighUpBtn; public Button getUserBtn; public TMP_Text result_Text; void Start() { this.user_Uid = tmp_User_Uid.text; this.SignUpTabBtn.onClick.AddListener(() => { this.SignUpGO.SetActive(true); this.GetUserGO.SetActive(false); }); this.GetUserTabBtn.onClick.AddListener(() => { this.SignUpGO.SetActive(false); this.GetUserGO.SetActive(true); }); HTTPManager.instance.getSignUpResult = (packet) => { Debug.LogFormat("HTTPManager.instance.getSignUpResult : {0}", packet) ; switch (packet) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 등록 완료", packet); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 이미 등록된 유저입니다.", packet); break; case 202: this.result_Text.text = string.Format("status_code : {0}, 중복된 닉네임 입니다.", packet); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet); break; } }; HTTPManager.instance.getGetUserResult = (packet) => { switch (packet.statusCode) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 검색 완료\n", packet.statusCode); this.result_Text.text += string.Format("NickName : {0}", packet.nickname); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 서버에 등록되지 않은 유저입니다.", packet.statusCode); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet.statusCode); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet.statusCode); break; } }; this.sighUpBtn.onClick.AddListener(() => { this.user_NickName = this.userNickName_IF.text; Debug.LogFormat("TMP_InputField : {0}", this.user_NickName); if (string.IsNullOrEmpty(this.user_NickName) && string.IsNullOrEmpty(this.user_Uid)) { this.result_Text.text = string.Format("닉네임을 입력해주세요."); } else { Debug.LogFormat("{0}, {1}", this.user_Uid, this.user_NickName); var packet = new Packets.req_nasSignUp() { user_uid = this.user_Uid, nickname = this.user_NickName }; HTTPManager.instance.RequestSignup("/user/nasSignUp",packet); } }); this.getUserBtn.onClick.AddListener(() => { if (string.IsNullOrEmpty(this.UserUid_IF.text)) { this.result_Text.text = string.Format("유저의 UID를 입력해주세요."); } else { var packet = new Packets.req_nasGetUser() { user_uid = this.UserUid_IF.text }; HTTPManager.instance.RequestGetUser("/user/nasGetUser", packet); } }); } }
다음은 Uid로 유저를 삭제해보자








HTTPManager.cs – SignOut 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using Newtonsoft.Json; using System.Text; public class HTTPManager : MonoBehaviour { public static HTTPManager instance; public string host = ""; public int port = ; public System.Action<int> getSignUpResult; public System.Action<Packets.res_nasGetUser> getGetUserResult; public System.Action<int> getSignOutResult; // 싱글톤으로 만들어주자 private void Awake() { HTTPManager.instance = this; } private void OnDestroy() { HTTPManager.instance = null; } // uri => /user/signup public void RequestSignup(string uri, Packets.req_nasSignUp packet) { StartCoroutine(this.RequestSignupImpl(uri, packet)); } private IEnumerator RequestSignupImpl(string uri, Packets.req_nasSignUp packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); Debug.Log(url); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_signup = JsonConvert.DeserializeObject<Packets.res_nasSignUp>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}", res_signup.statusCode); this.getSignUpResult(res_signup.statusCode); } else { this.getSignUpResult(500); Debug.LogFormat("에러"); } www.Dispose(); } public void RequestGetUser(string uri, Packets.req_nasGetUser packet) { StartCoroutine(this.RequestGetUserImpl(uri, packet)); } private IEnumerator RequestGetUserImpl(string uri, Packets.req_nasGetUser packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); Debug.Log(url); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_getuser = JsonConvert.DeserializeObject<Packets.res_nasGetUser>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}, nickName : {1}", res_getuser.statusCode, res_getuser.nickname); this.getGetUserResult(res_getuser); } else { Packets.res_nasGetUser res_getuser = new Packets.res_nasGetUser(); res_getuser.statusCode = 500; res_getuser.nickname = ""; this.getGetUserResult(res_getuser); Debug.LogFormat("에러"); } www.Dispose(); } public void RequestSignOut(string uri, Packets.req_nasSignOut packet) { StartCoroutine(this.RequestSignOutImpl(uri, packet)); } private IEnumerator RequestSignOutImpl(string uri, Packets.req_nasSignOut packet) { var url = string.Format("{0}:{1}{2}", this.host, this.port, uri); var www = new UnityWebRequest(url, "POST"); //객체를 -> 문자열 직렬화 var json = JsonConvert.SerializeObject(packet); //문자열 -> byte배열로 직렬화 var rawdata = Encoding.UTF8.GetBytes(json); www.uploadHandler = new UploadHandlerRaw(rawdata); //요청 www.downloadHandler = new DownloadHandlerBuffer(); //응답 www.SetRequestHeader("Content-Type", "application/json"); yield return www.SendWebRequest(); if (www.result == UnityWebRequest.Result.Success) { Debug.LogFormat("--->{0}", www.downloadHandler.text); var res_signup = JsonConvert.DeserializeObject<Packets.res_nasSignOut>(www.downloadHandler.text); //역직렬화 Debug.LogFormat("status : {0}", res_signup.statusCode); this.getSignOutResult(res_signup.statusCode); } else { this.getSignOutResult(500); Debug.LogFormat("에러"); } www.Dispose(); } }
Packets.cs – SignOut 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Packets { /* 유저 등록(/user/nasSignUp) statusCode 200 유저 등록 완료 201 이미 등록된 유저 202 중복 닉네임 500 서버 에러 */ public class req_nasSignUp { public string user_uid; public string nickname; } public class res_nasSignUp { public int statusCode; } /* 유저 검색 (/user/nasGetUser) statusCode 200 유저 검색 완료 201 등록 되지 않는 유저 500 서버 에러 */ public class req_nasGetUser { public string user_uid; } public class res_nasGetUser { public int statusCode; public string nickname; } /* 유저 탈퇴 (/user/nasSignOut) statusCode 200 유저 탈퇴 완료 201 등록 되지 않는 유저 500 서버 에러 */ public class req_nasSignOut { public string user_uid; } public class res_nasSignOut { public int statusCode; } }
RestTestMain.cs – SignOut 추가
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class RestTestMain : MonoBehaviour { public Button SignUpTabBtn; public Button GetUserTabBtn; public Button SignOutTabBtn; public GameObject SignUpGO; public GameObject GetUserGO; public GameObject SignOutGO; public TMP_Text tmp_User_Uid; private string user_Uid; public TMP_InputField userNickName_IF; private string user_NickName; public TMP_InputField UserUid_IF; public Button sighUpBtn; public Button getUserBtn; public Button SignOutBtn; public TMP_InputField UserUid_IF_SignOut; public TMP_Text result_Text; void Start() { this.user_Uid = tmp_User_Uid.text; this.SignUpTabBtn.onClick.AddListener(() => { this.SignUpGO.SetActive(true); this.GetUserGO.SetActive(false); this.SignOutGO.SetActive(false); }); this.GetUserTabBtn.onClick.AddListener(() => { this.SignUpGO.SetActive(false); this.GetUserGO.SetActive(true); this.SignOutGO.SetActive(false); }); this.SignOutTabBtn.onClick.AddListener(() => { this.SignUpGO.SetActive(false); this.GetUserGO.SetActive(false); this.SignOutGO.SetActive(true); }); HTTPManager.instance.getSignUpResult = (packet) => { Debug.LogFormat("HTTPManager.instance.getSignUpResult : {0}", packet) ; switch (packet) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 등록 완료", packet); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 이미 등록된 유저입니다.", packet); break; case 202: this.result_Text.text = string.Format("status_code : {0}, 중복된 닉네임 입니다.", packet); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet); break; } }; HTTPManager.instance.getGetUserResult = (packet) => { switch (packet.statusCode) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 검색 완료\n", packet.statusCode); this.result_Text.text += string.Format("NickName : {0}", packet.nickname); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 서버에 등록되지 않은 유저입니다.", packet.statusCode); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet.statusCode); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet.statusCode); break; } }; HTTPManager.instance.getSignOutResult = (packet) => { switch (packet) { case 200: this.result_Text.text = string.Format("status_code : {0}, 유저 탈퇴 완료", packet); break; case 201: this.result_Text.text = string.Format("status_code : {0}, 등록되지 않은 유저입니다.", packet); break; case 500: this.result_Text.text = string.Format("status_code : {0}, 서버가 응답이 없습니다.", packet); break; default: this.result_Text.text = string.Format("status_code : {0}, 이거 뜨면 망하는 겁니다.", packet); break; } }; this.sighUpBtn.onClick.AddListener(() => { this.user_NickName = this.userNickName_IF.text; Debug.LogFormat("TMP_InputField : {0}", this.user_NickName); if (string.IsNullOrEmpty(this.user_NickName) && string.IsNullOrEmpty(this.user_Uid)) { this.result_Text.text = string.Format("닉네임을 입력해주세요."); } else { Debug.LogFormat("{0}, {1}", this.user_Uid, this.user_NickName); var packet = new Packets.req_nasSignUp() { user_uid = this.user_Uid, nickname = this.user_NickName }; HTTPManager.instance.RequestSignup("/user/nasSignUp",packet); } }); this.getUserBtn.onClick.AddListener(() => { if (string.IsNullOrEmpty(this.UserUid_IF.text)) { this.result_Text.text = string.Format("유저의 UID를 입력해주세요."); } else { var packet = new Packets.req_nasGetUser() { user_uid = this.UserUid_IF.text }; HTTPManager.instance.RequestGetUser("/user/nasGetUser", packet); } }); this.SignOutBtn.onClick.AddListener(() => { if (string.IsNullOrEmpty(this.UserUid_IF_SignOut.text)) { this.result_Text.text = string.Format("유저의 UID를 입력해주세요."); } else { var packet = new Packets.req_nasSignOut() { user_uid = this.UserUid_IF_SignOut.text }; HTTPManager.instance.RequestSignOut("/user/nasSignOut", packet); } }); } }