지난 글에 이어서
데이터베이스와 로그인 시스템을 연동하기 위한 방법을 알아보자 !
using System.Linq;
using MySql.Data.MySqlClient;
using Mysqlx.Crud;
using System.Collections.Generic;
//string _server = "121.168.117.23"; //DB 서버 주소, 로컬일 경우 localhost
//int _port = 3306; //DB 서버 포트
//string _database = "db_spacescore"; //DB 이름
//string _id = "allen"; //계정 아이디
//string _pw = "qezvRC*Kf*bTDA4sKCd_TGe-"; //계정 비밀번호
//string _connectionAddress = "";
namespace Database
{
public class dataform
{
private string _server;
private int _port;
private string _database;
private string _id;
private string _pw;
private string _connectionAddress;
private MySqlConnection _connection;
public dataform(string server, int port, string database, string id, string pw)
{
this._server = server; //DB 서버 주소, 로컬일 경우 localhost
this._port = port; //DB 서버 포트
this._database = database; //DB 이름
this._id = id; //계정 아이디
this._pw = pw; //계정 비밀번호
//InitializeComponent();
//MySQL 연결을 위한 주소 형식
this._connectionAddress = string.Format($"Server={_server};Port={_port};Database={_database};Uid={_id};Pwd={_pw}");
this._connection = new MySqlConnection(this._connectionAddress); // SQL 서버와 위의 주소값 연결
this._connection.Open(); //SQL 서버 연결
}
~dataform()
{
this._connection.Close();
}
}
}
우선 본래 1차로 구현했던 DB에 직접적으로 접근하던 방식으로 사용했던 코드를 수정해서 사용하기로 했다.
위의 해당 코드에서는 DB서버에 접근하기 위해
서버 주소, 포트 명, 내 DB 로그인용 아이디, 비밀번호 등등 여러 민감한 정보들을 직접적으로 기입한 후
접근이 성공적이라면 DB에 올라가있는 데이터들을 순차적으로 C#에 맞게 틀(Class)을 짜준 후
내가 원하는 방식으로 데이터를 받아오는 방법이었다.
public void InsertData(string _initial, int _score) // 데이터 삽입 함수
{
try
{
string insertQuery = string.Format($"INSERT INTO tb_vslikedata (id, point) VALUES ('{_initial}', {_score});"); // 쿼리로 추가할 데이터값 입력. (format 안쪽은 Query 문법으로 선언)
MySqlCommand command = new MySqlCommand(insertQuery, this._connection); // MySqlCommand 는 MySql로 명령어를 전송하는 클래스. insertQuery값과 보낼 주소를 입력해 연결 시도.
command.ExecuteNonQuery(); // Insert 쿼리를 실행, 데이터를 데이터베이스에 삽입.
Console.WriteLine("데이터 업로드 완료."); // 완료 메세지
}
catch (Exception ex)
{
Console.WriteLine("오류입니다. " + ex.Message); // 실패시 메세지
}
}
이런식으로 데이터를 삽입하려면 Query문의 문법에 맞게 먼저 명령어를 기입해 주고,
DB에 올리려는 _initial 값과 _score를 넣어주고 나머지는 MYsql에 명령어와 주소를 전송해준다.
static void Main(string[] args)
{
dataform df = new dataform("121.168.117.23", 3306, "db_vslikeinfo", "allen", "비밀번호");
df.InsertData("Jeon", 2000);
}
이후 main 문에서 dataform 작성 후 원하는 함수를 불러주면 값은 성공적으로 들어간다.
여기까지 잘 돌아가는걸 확인 했기 때문에 서버 주소와 개인정보를 올려주는 곳에
Restful Api를 이용해 URL만 기입하는 식으로 코드를 변경해보기로 했다.
우선 Unity에서 실행하기 전 Visual Studio에서 c#으로 먼저 구현 후 Unity에 맞는 문법으로 변경하기로 한다.
Unity에서도 디버깅은 가능하지만 원하는 타이밍에 멈추고 에러를 잡을때 Unity 없이 수행하는 것이 항상
빠르고 구조를 잡기 용이했다.
지난 시간에 작성한 통신 규약 정의를 참고해 보면
URL 주소가 각 4개의 함수와 연결되어 있는걸 볼 수 있다.
제일 먼저 계정을 생성할 때 실행할 함수는 create_account 이고
id와 pw를 전송하면 data로 msg를 수신받는 형식이다.
msg는 성공의 경우와 실패의 경우로 나눠서 전송 받았고, 혹여나 아이디가 겹친다면 "ID Already Exist" 라는 msg를
전송받는다.
여기서 중요한 것은 먼저 올바른 데이터 값을 형식에 맞게 보내야 하고
데이터를 수신 받을때도 꼭 데이터 수신에 알맞은 형식으로 수신받아야 한다는 점이다.
정보를 Json으로 주고 받기 때문에 해당 Json을 받을 class의 구조를 꼭 알맞게 만들어 주어야 한다.
(대부분의 에러가 여기서 발생함)
public class loginParams
{
public string? id { get; set; }
public string? pw { get; set; }
}
// create, login
public class loginRequest
{
public string? api { get; set; }
public loginParams? @params { get; set; }
}
계정 생성과 로그인 시에 보내줄 파라미터가 같기 때문에 더 많은 응답 데이터를 확인 할 수 있는
로그인 처리 먼저 구현해 보자.
자료형 뒤에 ?를 붙이는 것은 변수에 Null 값을 허용하는 것이고
@는 예약어 처리를 하는것인데, params라는 변수 이름이 기존 class에서 사용이 안되는 이름이지만
다른 이름으로 하기에는 가독성이 떨어져 부득이 하게 예약어 처리를 했다.
LoginRequest 해줄 때 함수 이름을 기입해줄 api와 회원가입 할 id 와 pw를 로그인 요청에 필요한 class로
만들었다.
public class MyLoginResponse
{
public string? api { get; set; }
public int code { get; set; }
public MyLoginResponseData? data;
}
public class MyLoginResponseData
{
public string? token { get; set; }
public int? score { get; set; }
public string? msg { get; set; }
}
이후 전송 받은 데이터를 처리할 class 역시 msg와 token, 그리고 기존에 게임을 플레이하며 모아두었던 점수를
다시 확인할 score 까지 만들어 둔다.
여기까지는 간단하게 class로 구현할 수 있고 이제는 Restful Api에 요청 보낼 함수를 구현할 차례이다.
먼저 DB에 접근하는 함수를 구현할때는 많은 사람들이 가급적 비동기로 처리한다고 한다.
상황에 따라 다르겠지만 DB에 접근하는 경우에 네트워크 지연이나 기타 사유로 응답을 늦게 받는 경우가 종종 있는데,
이 시간동안 다른 동작을 하지 못하는건 전체적인 시스템 성능이 낮아지기 때문에 비동기로 처리했다.
비동기와 동기 처리에 관한 자세한 내용은 추후 다시 한번 배워보도록 하자.
static async Task api_create_account(string id, string pw)
{
// POST할 URL
string url = "http://ted-rpi4-dev.duckdns.org:65500/api/create_account";
try
{
// 보낼 json 데이터 생성
loginRequest postdata = new loginRequest()
{
api = "create_account",
@params = new loginParams()
{
id = id,
pw = pw
},
};
// json 데이터를 문자열로 변환
string json = JsonConvert.SerializeObject(postdata);
// JSON 데이터를 StringContent로 변환
var content = new StringContent(json, Encoding.UTF8, "application/json");
// HttpClient 인스턴스 생성
using (HttpClient client = new HttpClient())
{
// POST 요청 보내기
HttpResponseMessage response = await client.PostAsync(url, content);
// 응답 확인
if (response.IsSuccessStatusCode)
{
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("서버 응답:");
Console.WriteLine(responseBody);
}
else
{
Console.WriteLine("서버 오류: " + response.StatusCode);
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine("서버 응답:");
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine("에러 발생: " + ex.Message);
}
}
구조가 상당히 복잡해 보이지만 하나씩 뜯어보도록 하자.
먼저 URL과 내가 보낼 데이터를 Json으로 변경 해야 한다.
이를 JsonConvert로 변환해 주고
이 Json 데이터를 Http와 통신하기 위해서는 다시 StringContent라는 객체로 감싸주어야 한다.
이후 HttpClient 클래스를 사용해 웹 서버에 HTTP 요청을 보내고
성공 했는지 응답을 받으면 된다.
이때 async 비동기로 함수를 요청하기 때문에 응답은 await로 받아준다.
await는 async로 작성된 함수 내에서 해당 작업이 완료될 때 까지 응답을 기다리는 키워드이다.
이제 이 함수를 main에서 돌려보자.
static async Task Main(string[] args)
{
string id = "jy2";
string pw = "753159";
await api_create_account(id, pw);
}
만들 아이디와 비밀번호를 대강 넣어주고
실행해 보면
정상적으로 계정이 생성됨을 볼 수 있다.
이후 Unity에서는
Console.WriteLine(); 을 Debug.Log(); 정도로 바꿔주고
계정 생성을 원하는 타이밍에 맞게만 동작하는 방법으로 특정 부분들을 수정한다면 바로 사용이 가능하다.
계정 생성이 올바르게 동작했고
응답도 올바르게 왔다.
DB에도 올바르게 회원가입 정보가 들어가 있는걸 확인 했다.
나머지 로그인 후 로그아웃, 점수 확인등의 함수는 비슷한 방식으로
데이터를 전송해 줄 class와 전송 받을 class의 구조만 만들어주면 쉽게?? 구현할 수 있다.
'Unity' 카테고리의 다른 글
Unity [디자인 패턴] - 싱글톤 패턴 (0) | 2024.08.07 |
---|---|
Unity [디자인 패턴] - 디자인 패턴이란? (0) | 2024.08.07 |
Unity - 물리 엔진(RigidBody, Collider) (2) | 2024.07.22 |
Unity [디자인 패턴] - 오브젝트 풀링 패턴 (0) | 2024.04.30 |
Unity에서 DB를 활용해 로그인, 회원가입 시스템 구현해보기 (1) (0) | 2024.04.22 |