- 非异步请求:
- post请求:
/// <summary>
/// 回调验证证书
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="errors"></param>
/// <returns></returns>
public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; // 总是接受
}
/// <summary>
/// HTTPS Post请求
/// </summary>
/// <param name="URL">访问地址</param>
/// <param name="strPostData">携带数据</param>
/// <param name="func">回调lua方法</param>
/// <returns></returns>
public void HttpsPost(string URL, string strPostData, LuaFunction func)
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.Accept = "text/html, application/xhtml+xml, *";
request.ContentType = "application/x-www-form-urlencoded";
byte[] buffer = encoding.GetBytes(strPostData);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
func.Call(reader.ReadToEnd());
}
}
func是回调到lua中,在reader.ReadToEnd()已经拿到返回的数据;
CheckValidationResult()这个方法是证书的验证,每次验证的时候都是忽略证书,项目中的证书是服务端同学自己写的一套证书验证,所以每次都是忽略掉就行了。
- get请求:
/// <summary>
/// HTTPS Post请求
/// </summary>
/// <param name="URL">访问地址</param>
/// <param name="strPostData">携带数据</param>
/// <param name="func">回调lua方法</param>
/// <returns></returns>
public void HttpsPost(string URL, string strPostData, LuaFunction func)
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
Encoding encoding = Encoding.UTF8;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.CookieContainer = new CookieContainer();
request.Method = "POST";
request.Accept = "text/html, application/xhtml+xml, *";
request.ContentType = "application/x-www-form-urlencoded";
byte[] buffer = encoding.GetBytes(strPostData);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")))
{
func.Call(reader.ReadToEnd());
}
}
/// <summary>
/// HTTPS get请求
/// </summary>
/// <param name="url">访问地址</param>
/// <param name="func">lua回调</param>
public void HTTPSGet(string url, LuaFunction func)
{
try
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
req.Method = "GET";
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
Stream stream = res.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
{
func.Call(reader.ReadToEnd());
}
}
catch (System.Exception ex)
{
Debug.LogError(ex);
}
}
- 异步请求:
如果游戏使用Socket,在网络不好的情况,使用HTTPS,服务端没有响应,会导致主线程挂机的操作,影响到socket的通信,所以项目中要使用异步的操作。下面是异步的代码:
public void HttpsPostAsyn(string url, string strPostData, LuaFunction func)
{
Asyncdelegate isgt = new Asyncdelegate(Commit);
IAsyncResult ar = isgt.BeginInvoke(url, strPostData, func, null, new AsyncCallback(CallbackMethod), isgt);
}
//定义委托
public delegate void Asyncdelegate(string url, string strPostData, LuaFunction func, WebProxy objName);
//异步调用完成时,执行回调方法
private void CallbackMethod(IAsyncResult ar)
{
Asyncdelegate dlgt = (Asyncdelegate)ar.AsyncState;
dlgt.EndInvoke(ar);
Debug.Log("dlgt:" + dlgt);
Debug.Log("ar:" + ar);
}
//向APM接口提交数据
//为什么要用WebProxy,因为.Net 4.0以下没有Host属性,无法设置标头来做DNS重连
public virtual void Commit(string url, string strPostData, LuaFunction func, WebProxy objName = null)
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
string ret = string.Empty;
string ip = string.Empty;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";//
request.Timeout = 30000;
request.ContentType = "application/x-www-form-urlencoded";
request.ServicePoint.Expect100Continue = false;
if (objName != null)
{
request.Proxy = objName;
}
Debug.Log("strPostData:" + strPostData);
//strPostData = UrlEncode(strPostData);
Debug.Log("strPostData:" + strPostData);
byte[] byteArray = Encoding.UTF8.GetBytes(strPostData);
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Debug.Log("responseFromServer:" + responseFromServer);
func.Call(responseFromServer);
reader.Close();
dataStream.Close();
response.Close();
}
catch (WebException ex)
{
Debug.LogError("链接失败:" + ex.Status.ToString());
if (ex.Status.ToString().Equals("NameResolutionFailure"))//域名解释错误,重连一次,重新获取域名ip,用ip来拼接提交
{
//ip = this.DnRetryGet("域名");
//if (ip.Equals("0"))
//{
// return
//}
//WebProxy proxy = new WebProxy(ip, 80);
//this.Commit(proxy);
}
}
}
PS:在发送数据时,可能会加载一些‘+’‘*’,在C#和java中会被服务端解析成“空格” 如果出现这种情况,可以使用
WWW.EscapeURL包一下发送的数据。
因为项目的需要可以分装一个方法供大家参考
public string UrlEncode(string str)
{
string[] s1 = str.Split('&');
string encodeStr = "";
for (int i = 0; i < s1.Length; i++)
{
string[] s1Split = s1[i].Split('=');
if (i == s1.Length - 1)
{
encodeStr = encodeStr + WWW.EscapeURL(s1Split[0]) + "=" + WWW.EscapeURL(s1Split[1]);
}
else
{
encodeStr = encodeStr + WWW.EscapeURL(s1Split[0]) + "=" + WWW.EscapeURL(s1Split[1]) + "&";
}
}
return encodeStr;
}