1. 비밀번호 암호화
node.js route의 member.js에서
crypto 모듈을 사용해서 비밀번호를 암호화 해줌
비밀번호를 암호화하는 function을 만들어준다.
post부분에 추가해준다
암호화된 비밀번호가 길어져서 안 들어올 수 도 있으므로 비밀번호 문자열데이터 길이를 늘려준다.
DB에서 테이블을 수정해주고
자바스크립트에서 member.js에서 password type을 수정해줌
DB에 비밀번호가 암호화 되어서 들어옴
2. 등록
등록 UI를 만들어준다.
SignUp 클래스를 만들어주고
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UISignUp : MonoBehaviour
{
public InputField inputMemberName;
public InputField inputPassword;
public Button btnSubmit;
public void Init()
{
}
}
test 클래스 start 부분에 init( )하고 작성해줌
this.uISignUp.btnSubmit.onClick.AddListener(() =>
{
var memberName = this.uISignUp.inputMemberName.text;
var password = this.uISignUp.inputPassword.text;
Debug.LogFormat("{0},{1}", memberName, password);
var req = new Protocols.req_member_post();
req.username = memberName;
req.password = password;
this.SignUp(req);
});
public void SignUp(Protocols.req_member_post req)
{
//로딩바 켜줌
this.loading.SetActive(true);
StartCoroutine(this.Post1("/member", req, (responseCode) =>
{
//로딩바 꺼줌
this.loading.SetActive(false);
if (responseCode == 200)
{
Debug.Log("가입 완료");
}
}));
}
//form으로 보내기
//body로 보내는 방법도 있음
private IEnumerator Post1(string uri, Protocols.req_member_post req, System.Action<long> onComplete)
{
//List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
var form = new WWWForm();
form.AddField("username", req.username);
form.AddField("password", req.password);
var url = string.Format("{0}:{1}{2}", host, port, uri);
var www = UnityWebRequest.Post(url, form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
3. 수정
팝업 창을 보여줄 prompt 오브젝트를 만들고 스크립트도 만듦
비활성화 해놨다가 멤버 리스트의 수정 버튼을 누르면 나타나고
변경한 이름 적고 등록 버튼을 누르거나 취소 버튼을 누르면 사라지게 함
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class UIPopUpPrompt : MonoBehaviour
{
public InputField inputNewMemberIndexName;
public Button btnOkay;
public Button btnCancel;
public UnityAction<int, string> OnClickOk;
private int id;
public void Init()
{
this.btnOkay.onClick.AddListener(() =>
{
this.OnClickOk(this.id, this.inputNewMemberIndexName.text);
});
}
public void Close()
{
this.gameObject.SetActive(false);
}
public void Open(int id)
{
this.id = id;
this.gameObject.SetActive(true);
}
}
멤버 리스트의 수정 버튼을 눌렀을 때 대리자를 호출함
UIMembers 의 Refresh 메서드의 멤버들을 생성하는 foreach문에 써준다.
listItem.btnUpdata.onClick.AddListener(() =>
{
this.OnUpdateClick(member.id, member.username);
});
test 의 start 부분에 대리자 정의를 써줌
팝업이 열림
//수정
this.uiMembers.OnUpdateClick = (id, username) =>
{
Debug.LogFormat("{0},{1}", id, username);
this.uiPopUpPrompt.Open(id);
};
UIPopUpPrompt 를 start 에서 init 해주고
나타난 팝업에서 변경한 이름을 적고 등록버튼(btnOkay)를 누르면 호출되는 대리자를 정의해줌
this.uiPopUpPrompt.Init();
this.uiPopUpPrompt.OnClickOk = (id, newMemberName) =>
{
//test 에서 id를 전역변수로 갖고 값을 저장해서 보내는 것보다
//이 방법이 낫다!
//id와 membername을 서버에 보냄
Debug.LogFormat("{0},{1}", id, newMemberName);
var req = new Protocols.req_member_put();
req.username = newMemberName;
this.UpdateMemberName(id, req);
};
UpdateMemberName 메서드에서 변경할 id를 담은 uri를 만들고 put 코루틴 시작
public void UpdateMemberName(int id, Protocols.req_member_put req)
{
var uri = string.Format("/member/{0}", id);
StartCoroutine(this.Put(uri, req, (responseCode) =>
{
Debug.Log(responseCode);
}));
this.uiPopUpPrompt.Close();
}
서버로 url과 req를 보냄
직렬화하고 01010001로 인코딩해서 보냄
유니티에서는 patch의 기능을 put이 하는데
www.method ="PATCH";
하면 member.js의 patch로 보낼 수 있음
//Unity에서는 Patch의 기능을 Put이 함
private IEnumerator Put(string uri, Protocols.req_member_put req, System.Action<long> onComplete)
{
var url = string.Format("{0}:{1}{2}", host, port, uri);
var json = JsonConvert.SerializeObject(req);
var data = Encoding.UTF8.GetBytes(json);
var www = UnityWebRequest.Put(url, data);
www.SetRequestHeader("Content-Type", "application/json");
//www.method = "PATCH"; //=> node.js에 patch로 들어간다.
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
route 의 member.js에서 put 기능을 추가해줌
취소 버튼 누르면 닫기
this.uiPopUpPrompt.btnCancel.onClick.AddListener(() =>
{
this.uiPopUpPrompt.Close();
});
4. 삭제
멤버리스트에서 삭제버튼을 누르면 멤버를 삭제시킬 거임
UIMember 클래스의 Refresh메서드 멤버들 접근하는 foreach부분에
삭제버튼을 누르면 id를 넘겨주는 대리자를 호출하게 함
listItem.btnDelete.onClick.AddListener(() =>
{
this.OnDeleteClick(member.id);
});
test의 start부분에서 정의해줌
//삭제
this.uiMembers.OnDeleteClick = (id) =>
{
this.DeleteMember(id);
};
멤버 uri만들고 코루틴으로 넘겨줌
//삭제
public void DeleteMember(int id)
{
var uri = string.Format("/member/{0}", id);
StartCoroutine(this.Delete(uri, (responseCode) =>
{
Debug.Log(responseCode);
}));
}
private IEnumerator Delete(string uri, System.Action<long> onComplete)
{
var url = string.Format("{0}:{1}{2}", host, port, uri);
var www = UnityWebRequest.Delete(url);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
결과
전체 코드
Test
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
public UIMembers uiMembers;
public UISignUp uISignUp;
public GameObject loading;
public UIPopUpPrompt uiPopUpPrompt;
private string host = "http://localhost";
private int port = 3000;
void Start()
{
this.uISignUp.Init();
this.uiPopUpPrompt.Init();
this.uiPopUpPrompt.OnClickOk = (id, newMemberName) =>
{
//test 에서 id를 전역변수로 갖고 값을 저장해서 보내는 것보다
//이 방법이 낫다!
//id와 membername을 서버에 보냄
Debug.LogFormat("{0},{1}", id, newMemberName);
var req = new Protocols.req_member_put();
req.username = newMemberName;
this.UpdateMemberName(id, req);
};
this.uiPopUpPrompt.btnCancel.onClick.AddListener(() =>
{
this.uiPopUpPrompt.Close();
});
this.uISignUp.btnSubmit.onClick.AddListener(() =>
{
var memberName = this.uISignUp.inputMemberName.text;
var password = this.uISignUp.inputPassword.text;
Debug.LogFormat("{0},{1}", memberName, password);
var req = new Protocols.req_member_post();
req.username = memberName;
req.password = password;
this.SignUp(req);
});
this.uiMembers.Init();
//수정
this.uiMembers.OnUpdateClick = (id, username) =>
{
Debug.LogFormat("{0},{1}", id, username);
this.uiPopUpPrompt.Open(id);
};
//삭제
this.uiMembers.OnDeleteClick = (id) =>
{
this.DeleteMember(id);
};
//새로고침
this.uiMembers.btnRefresh.onClick.AddListener(() =>
{
this.GetMembers();
});
this.GetMembers();
}
public void SignUp(Protocols.req_member_post req)
{
//로딩바 켜줌
this.loading.SetActive(true);
StartCoroutine(this.Post1("/member", req, (responseCode) =>
{
//로딩바 꺼줌
this.loading.SetActive(false);
if (responseCode == 200)
{
Debug.Log("가입 완료");
}
}));
}
public void GetMembers()
{
//로딩바 껴줌
this.loading.SetActive(true);
StartCoroutine(this.Get("/member", (res) =>
{
if (res.status == 200)
{
this.uiMembers.Refresh(res.members);
}
else
{
Debug.LogFormat("{0}", res.status);
}
//로딩바 꺼줌
this.loading.SetActive(false);
}));
}
//수정
public void UpdateMemberName(int id, Protocols.req_member_put req)
{
var uri = string.Format("/member/{0}", id);
StartCoroutine(this.Put(uri, req, (responseCode) =>
{
Debug.Log(responseCode);
}));
this.uiPopUpPrompt.Close();
}
//삭제
public void DeleteMember(int id)
{
var uri = string.Format("/member/{0}", id);
StartCoroutine(this.Delete(uri, (responseCode) =>
{
Debug.Log(responseCode);
}));
}
//처음 실행할때 조회
private IEnumerator Get(string uri, System.Action<Protocols.res_member_get> onComplete)
{
var url = string.Format("{0}:{1}{2}", host, port, uri);
Debug.Log(url);
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.LogFormat("{0}", www.error); //보통 밖에서 에러 처리 해주는게 좋음
}
else
{
var result = www.downloadHandler.data;
var json = Encoding.UTF8.GetString(result);
Protocols.res_member_get res = JsonConvert.DeserializeObject<Protocols.res_member_get>(json);
Debug.LogFormat("status: {0}, member cnt: {1}", res.status, res.members.Count());
onComplete(res);
}
}
//form으로 보내기
//body로 보내는 방법도 있음
private IEnumerator Post1(string uri, Protocols.req_member_post req, System.Action<long> onComplete)
{
//List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
var form = new WWWForm();
form.AddField("username", req.username);
form.AddField("password", req.password);
var url = string.Format("{0}:{1}{2}", host, port, uri);
var www = UnityWebRequest.Post(url, form);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
//Unity에서는 Patch의 기능을 Put이 함
private IEnumerator Put(string uri, Protocols.req_member_put req, System.Action<long> onComplete)
{
var url = string.Format("{0}:{1}{2}", host, port, uri);
var json = JsonConvert.SerializeObject(req);
var data = Encoding.UTF8.GetBytes(json);
var www = UnityWebRequest.Put(url, data);
www.SetRequestHeader("Content-Type", "application/json");
//www.method = "PATCH"; //=> node.js에 patch로 들어간다.
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
private IEnumerator Delete(string uri, System.Action<long> onComplete)
{
var url = string.Format("{0}:{1}{2}", host, port, uri);
var www = UnityWebRequest.Delete(url);
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
Debug.Log(www.responseCode);
onComplete(www.responseCode);
}
}
}
Protocols
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Protocols
{
public class member
{
public int id;
public string username;
public string password;
public string created_at;
}
public class res_memeber
{
public int status;
}
//멤버 조회
public class res_member_get:res_memeber
{
public member[] members;
}
//멤버 삭제
public class res_member_delete : res_memeber
{
}
//멤버 등록
public class req_member_post
{
public string username;
public string password;
}
public class res_member_post : res_memeber
{
}
//멤버 이름 수정(patch)
public class req_member_put
{
public string username;
}
public class res_member_put : res_memeber
{
}
}
UIMembers
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class UIMembers : MonoBehaviour
{
public Button btnRefresh;
public Transform contentsTrans;
public UIlistItem uiListItemPrefabs;
public UnityAction<int, string> OnUpdateClick;
public UnityAction<int> OnDeleteClick;
public void Init()
{
}
public void Refresh(Protocols.member[] members)
{
foreach(Transform child in this.contentsTrans)
{
Destroy(child.gameObject);
}
foreach(var member in members)
{
var go = Instantiate<GameObject>(this.uiListItemPrefabs.gameObject, this.contentsTrans);
var listItem = go.GetComponent<UIlistItem>();
listItem.Init(member.id, member.username);
listItem.btnUpdata.onClick.AddListener(() =>
{
this.OnUpdateClick(member.id, member.username);
});
listItem.btnDelete.onClick.AddListener(() =>
{
this.OnDeleteClick(member.id);
});
}
}
}
UIlistItem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIlistItem : MonoBehaviour
{
public Text txtId;
public Text txtMemeberName;
public Button btnUpdata;
public Button btnDelete;
private int id;
private string memberName;
public void Init(int id, string memberName)
{
this.id = id;
this.memberName = memberName;
this.txtId.text = this.id.ToString();
this.txtMemeberName.text = this.memberName.ToString();
}
}
UISignUp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UISignUp : MonoBehaviour
{
public InputField inputMemberName;
public InputField inputPassword;
public Button btnSubmit;
public void Init()
{
}
}
UIPopUpPrompt
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class UIPopUpPrompt : MonoBehaviour
{
public InputField inputNewMemberIndexName;
public Button btnOkay;
public Button btnCancel;
public UnityAction<int, string> OnClickOk;
private int id;
public void Init()
{
this.btnOkay.onClick.AddListener(() =>
{
this.OnClickOk(this.id, this.inputNewMemberIndexName.text);
});
}
public void Close()
{
this.gameObject.SetActive(false);
}
public void Open(int id)
{
this.id = id;
this.gameObject.SetActive(true);
}
}
'C# > 수업내용' 카테고리의 다른 글
2020.08.04. 수업내용 - NGUI(1) (0) | 2020.08.04 |
---|---|
2020.07.31. 수업내용 - WebView (2) | 2020.07.31 |
2020.07.28. 수업내용 - DB 서버와 유니티 연동 ( MySQL, Nodejs, Unity)(1) (0) | 2020.07.28 |
2020.07.08. 수업내용 - 인공지능 강화학습2 ( 펭귄 MLAgent) (0) | 2020.07.08 |
2020.07.07. 수업내용 - 인공지능 강화학습 1 (0) | 2020.07.07 |