Unity3D 支持 https 请求,兼容 ipv6 only 网络
(1)使用 HttpWebRequest 进行 Https 访问
Unity 2018 版本之后,如果要使用 https 访问,直接使用替代 www 的 UnityWebRequest 即可,访问 https 只需要指定 certificateHandler 即可进行 https 权限验证。
但是之前的 Unity 版本,用 UnityWebRequest 访问 https 会遇到权限问题,导致无法访问。所以,最好的办法是使用 .Net 的 HttpWebRequest,需要注意的是:打 Android 版本不能使用 .NET 2.0 subset,否则会找不到有关的 library,需要完整的 .NET 2.0。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
//Https设置证书验证,配合 System.Net.WebRequest
ServicePointManager.ServerCertificateValidationCallback =
delegate (object s, X509Certificate cer, X509Chain chain, SslPolicyErrors sslError)
{
return true;
};
//UnityWebRequest要在Unity2018以上才能支持https,这里用 HttpWebRequest 替代
string responseData = null;
HttpWebResponse response = null;
Stream dataStream = null;
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
request.Timeout = 2000;
response = request.GetResponse() as HttpWebResponse;
if (response != null)
{
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
responseData = reader.ReadToEnd();
}
if (!string.IsNullOrEmpty(responseData))
{
Debug.LogFormat("Get Result {0}", responseData);
}
else
{
Debug.LogError("error");
}
}
catch(Exception e)
{
Debug.LogErrorFormat("Get Result Exception {0}", e)
}
finally
{
if (response != null)
response.Close();
if(dataStream != null)
dataStream.Close();
}
|
服务端要申请一个证书,一般是一个 .crt 文件(证书)和一个 .nopass(私钥) 文件,不同的服务端语言配置有所不同
(2)兼容 Ipv6 网络
所有 IP 地址要用域名替换,然后请求 DNS 得到真正的 IP 地址,在 IPV6 下得到的是 ipv6 地址,否则是 ipv4 地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public string ResolveDNS(string hostName)
{
try
{
var addr = Dns.GetHostAddresses(hostName)
if (addr != null && addr.Length > 0)
{
int index = Random.Range(0, addr.Length - 1);
var a = addr[index];
if (a != null)
{
return a.ToString();
}
}
}
catch(Exception e)
{
Debug.LogError("Exception " + e);
}
return string.Empty;
}
|
所有 TcpClient 等 Socket 连接对象需要传入 IPV6 的参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
TCpClient client = null;
IPAddress address;
if (!IPAddress.TryParse(host, out address))
{
Debug.LogError("Connect TryParse host error:" + host);
return;
}
if (address.AddressFamily == AddressFamily.InterNetworkV6)
{
client = new TcpClient(AddressFamily.InterNetworkV6);
}
else
{
client = new TcpClient(AddressFamily.InterNetwork);
}
|