많이들 쓰기는 Unity입니다.
그리고 최근 모바일 게임에서 많이 쓰이는 게 웹 응용 서버이죠.
그리고 웹 응용 프로그램에서 많이 쓰이는 쿠키와 세션…
Unity의 WWW, WWWForm 으로 세션을 유지하는 방법을 소개합니다.
[원본 링크]
아래처럼 세션을 유지하기 위한 쿠키 정보를 저장할 해시 테이블을 만들고
// will be set to some session id after login
private Hashtable session_ident = new Hashtable();
// and some helper functions and properties
public void ClearSessionCookie(){
session_ident["Cookie"] = null;
}
public void SetSessionCookie(string s){
session_ident["Cookie"] = s;
}
public Hashtable SessionCookie{
get { return session_ident; }
}
public string GetSessionCookie(){
return session_ident["Cookie"] as string;
}
public bool SessionCookieIsSet{
get { return session_ident["Cookie"] != null; }
}
그리고 로그인 응답으로부터 파싱해서 저장해 두었다가
// Failed=Bad server error, Error=server did reply with an error, OK=all fine
public enum ReturnCode : int { Failed=-1, Error=0, OK=1 }
public delegate void OnNetResult(ReturnCode code, string result);
public IEnumerator Login(OnNetResult callback, string nm, string pw)
{
// create params to send
WWWForm form = new WWWForm();
form.AddField("nm", nm);
form.AddField("pw", pw);
// let www do its thing
WWW www = new WWW("http://path_to/login/", form);
yield return www;
// the following code can be used to see what the SET-COOKIE contains
// Have a look at http://en.wikipedia.org/wiki/HTTP_cookie to see what Set-Cookie is all about
// It is bascially how the server will tell you what it expects you to be doing with the cookie
// The name you are looking for will be the first characters followed be "=", after that follows
// the value of the cookie. There could also be other entries on the same line like 'Expires'
// but they will all be seperated by ';'
//if (www.responseHeaders.ContainsKey("SET-COOKIE")){
// Debug.Log(www.responseHeaders["SET-COOKIE"]);
//}
// handle the data from www, but first check if there where errors
if (!string.IsNullOrEmpty(www.error) || string.IsNullOrEmpty(www.text))
{
errmsg = "Network communication error.";
if (callback != null) callback(ReturnCode.Failed, errmsg);
}
else
{
errmsg = "Network communication error.";
// like I mentioned in description, this code
// expects "1player_name" on success, else "0"
if (www.text[0] == '1')
{
try
{
// extract the public name of player
Game.Instance.name = www.text.Substring(1);
Game.Instance.ClearSessionCookie();
// check if session cookie was send, if not, well, no use to continue then
if (www.responseHeaders.ContainsKey("SET-COOKIE"))
{
// extract the session identifier cookie and save it
// the cookie will be named, "auth" (this could be something else in your case)
char[] splitter = { ';' };
string[] v = www.responseHeaders["SET-COOKIE"].Split(splitter);
foreach (string s in v)
{
if (string.IsNullOrEmpty(s)) continue;
if (s.Substring(0, 4).ToLower().Equals("auth"))
{ // found it
Game.Instance.SetSessionCookie(s);
break;
}
}
}
}
catch {
// this should only possibly happen during development
if (callback != null) callback(ReturnCode.Failed, "Network communication error.");
}
}
// let whomever is interrested know that the login succeeded or failed
if (callback != null)
{
if (www.text[0] == '1' && Game.Instance.SessionCookieIsSet)
{
callback(ReturnCode.OK, "Login ok");
}
else if (www.text[0] == '0' || !Game.Instance.SessionCookieIsSet)
{
errmsg = "Invalid login name or password.";
// my server sometimes sends "0some_explenation", therefore this next line
if (www.text.Length > 1) errmsg = www.text.Substring(1);
callback(ReturnCode.Error, errmsg);
}
else
{
// this should only happen during development since there was an unexpected
// value at [0], not 0 or 1 as expected, so probably some script error
errmsg = "Network communication error.";
callback(ReturnCode.Failed, errmsg);
}
}
}
}
다른 요청에서 헤더에 넣으면 됩니다
public IEnumerator NormalRequest(string url, OnNetResult callback, Dictionary p)
{
// p: is a set of keys and values where the key is the name and value the value for the post field
// create form to send with request
WWWForm form = new WWWForm();
if (p != null) {
foreach (KeyValuePair kv in p) form.AddField(kv.Key, kv.Value);
}
// let www do its thing, note that you send the SessionCookie along
WWW www = new WWW(url, form.data, Game.Instance.SessionCookie);
yield return www;
// ...
}