与服务器第一次交互采用Http连接的方式,使用Http方式完成账号登录,游戏房间登录.
账号登录
当玩家按下登录按钮后会连接服务器,采用的是WWW的方式.通过封装的AsyncWWWTask异步任务发送数据到服务器,如果登录成功会获得服务器返回的cookie(会作为登陆房间的凭证).
private void RequestHttpLogin()
{
var form = new WWWForm();
form.AddField("c", (int)MsgType.Login);
form.AddField("a", Account);
form.AddField("n", Uri.EscapeDataString(Name));
var toMd5 = ToMd5(Password);
form.AddField("p", Uri.EscapeDataString(toMd5));
form.AddField("ver", Uri.EscapeDataString("1"));
form.AddField("dev", Uri.EscapeDataString(SystemInfo.deviceUniqueIdentifier));
#if UNITY_ANDROID
form.AddField("device", Uri.EscapeDataString("android"));
#elif UNITY_IOS
form.AddField("device", Uri.EscapeDataString("ios"));
#else
form.AddField("device", Uri.EscapeDataString("pc"));
#endif
form.AddField("r", 1);
form.AddField("phonetype", Uri.EscapeDataString(DeviceModel));
form.AddField("switchacc", 0);
form.AddField("sign", Uri.EscapeDataString(ToMd5(Md5Key + (int)MsgType.Login)));
form.AddField("openid", Uri.EscapeDataString(""));
Service.UIManager.UILoading.SetVisible(true);
new AsyncWWWTask(p =>
{
if (!string.IsNullOrEmpty(p.error))
{
Service.UIManager.ShowPop(Singleton.GetInstance<Localization>().Get(ExcelManager.settings_error[1].error));
Debuger.LogError("error:" + p.error.ToString());
}
else if (p.isDone)
{
var receiveBytes = new ByteArray();
receiveBytes.WriteBytes(p.bytes);
var pack = CmdUtil.ParseCmd(receiveBytes);
var loginMsg = Serializer.Deserialize<RetLoginMsg>(pack.BodyStream);
ID = loginMsg.Id;
if (!_cookies.ContainsKey("COOKIE"))
{
_cookies.Add("COOKIE", p.responseHeaders["SET-COOKIE"]);
}
Service.UIManager.RoomUI();
Service.UIManager.UILoading.SetVisible(false);
}
}, Url, form.data).Start();
}
房间登录
账号登录成功后会弹出登陆房间UI面板,点击登录后会用之前获得的cookie请求登录游戏房间.如果登录成功会获得房间服地址和房间服key,自此Http流程结束.
private void TryInRoom()
{
var form = new WWWForm();
form.AddField("c", (int)MsgType.ReqIntoFRoom);
form.AddField("ver", Uri.EscapeDataString("1"));
form.AddField("model", "5");
form.AddField("scene", Common.SceneId.ToString());
form.AddField("ticketnum", "0");
var msgMd5 = ToMd5(Md5Key + (int)MsgType.ReqIntoFRoom);
form.AddField("sign", Uri.EscapeDataString(msgMd5));
Service.UIManager.UILoading.SetVisible(true);
new AsyncWWWTask(p =>
{
if (!string.IsNullOrEmpty(p.error))
{
Service.UIManager.ShowPop(ExcelManager.settings_error[3].error);
Debuger.LogError(p.ToString());
}
else if (p.isDone)
{
var receiveBytes = new ByteArray();
receiveBytes.WriteBytes(p.bytes);
var pack = CmdUtil.ParseCmd(receiveBytes);
if (pack.CmdId == (uint)MsgType.ErrorMsg)
{
Service.UIManager.ShowPop(ExcelManager.settings_error[3].error);
Debug.LogError(MsgType.ErrorMsg);
return;
}
var retIntoFRoom = Serializer.Deserialize<RetIntoFRoom>(pack.BodyStream);
RoomServerkey = retIntoFRoom.Key;
Dispatch(Module.EModele.Network_Tcp, new Message(TcpConnection.EMessageKey.RoomServer.ToString(), retIntoFRoom.Addr));
}
}, Url, form.data, _cookies).Start();
}
扩展:
异步任务:AsyncWWWTask继承自GameBox异步任务,通过IsDone检测异步任务是否完成,然后通过回调触发外部逻辑.
public class AsyncWWWTask : AsyncTask
{
private WWW www;
private Action<WWW> wwwEvent;
public AsyncWWWTask(Action<WWW> wwwEvent, string url, byte[] data = null, Dictionary<string, string> cookies = null) : base(false)
{
this.wwwEvent = wwwEvent;
if (cookies == null)
{
if (data == null)
{
this.www = new WWW(url);
}
else
{
this.www = new WWW(url, data);
}
}
else
{
this.www = new WWW(url, data, cookies);
}
}
protected override bool IsDone()
{
if (this.www.isDone)
{
this.wwwEvent(this.www);
return true;
}
return false;
}