RestServer + Unity DB연동

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의 원칙과 방법을 이용하여 웹애플리케이션을 만들기 위한 프레임워크이다.

https://expressjs.com/ko/

NPM

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

자신이 작성한 패키지를 공개할 수도 있고 필요한 패키지를 검색하여 재사용할 수도 있다.

https://www.npmjs.com/

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 개발의 생산성을 높여주는 플랫폼

https://www.postman.com/

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);
            }


        });

    }

    
}

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

위로 스크롤