UnityWebRequest与后端通信,对接口
注意:每个后端做的接口都会有些不同,根据实际更改。本文为案例。
本接口程序被设计用来支撑移动客户端部分功能,数据交换格式为JSON,接口若支持POST方式访问,则一般也支持GET方式访问(特殊情况除外,如:文件上传),最佳访问方式请参照各API定义中的建议。
提交数据方式
1、application/x-www-form-urlencoded
用于发送表单数据,数据会进行 URL 编码。
2、application/json
发送Json格式的数据。
3、multipart/form-data
用于发送带有文件上传的表单数据。
4、text/plain
发送纯文本数据
本文采用的是发送json格式数据。
_request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
安全性:
一般为了保证数据传输的完整和安全,不被篡改,都需要进行加密。
本文密钥:benwenmiyao (与后端确定的一段无规则字符串)
token和sign不进行再次加密。
本次传输的字符串都为小写。
签名规则
sign = sha1( (k1=v1&k2=v2...) + "secret=benwenmiyao" )
其中,k1 = v1&k2 = v2 …为参数键值列表,列表中的每一项格式为“键=值”,列表项需要根据键名升序排列,然后用“&”进行连接最后将数据传输秘钥secret拼接至尾端。整体作sha1运算得到最终的签名。
对所有参数按key按ASCⅡ码做升序排序,加密算法sha1。
比如入参是c=1&b=2&a=3,排序之后是a,b,c。把参数名和参数值连接成字符串,a=1&b=2&c=3,把secret连接到字符串的尾部:
a=1&b=2&c=3&secret=benwenmiyao
进行sha1加密。
sha1(“a=1&b=2&c=3&secret=benwenmiyao”)
加密
具体参考另一篇https://blog.csdn.net/weixin_44347839/article/details/134926493?spm=1001.2014.3001.5501
2个POST案例参考:
1、登录
请求体Body是字段moblie string类型 必填项,字段sign string类型 必填项。
2、获取好友列表
请求头header是字段token string类型 必填项(登录信息获取)。
实际代码参考
//请求地址+端口
public string UrlPath = "www.csdn.net";
public string LoginUrl = "/Login";
public string GetListUrl = "/GetList";
//密钥
private string secret="benwenmiyao";
public string mobile = "181XXXXXXXX";
//加密sign
private string sign;
// 登录成功返回得token
private string token;
public Dictionary<string, object> LoginDir(out string json)
{
Dictionary<string, object> dir = new Dictionary<string, object> {
{"mobile" ,mobile}
};
json = dir.HandJsonFormat();
return dir;
}
public Dictionary<string, object> LoginSignDir(out string json)
{
Dictionary<string, object> dir = new Dictionary<string, object> {
{"mobile" ,mobile},
{ "sign",SortMessage(LoginDir(out string t))}
};
json = dir.HandJsonFormat();
Debug.Log("mobile+sign" + json);
return dir;
}
/// <summary>
/// 对所有参数key按ASCⅡ码做升序排序 加密
/// </summary>
/// <returns></returns>
public string SortMessage(Dictionary<string, object> dir)
{
string output = string.Join("&", dir.OrderBy(kv => kv.Key)
.Select(kv => $"{kv.Key}={kv.Value}"));
output += ("&" + secret);
var sha1 = EncryptTool.Sha1(output).ToLower();
Debug.Log("未加密信息:" + output);
Debug.Log("sha1加密信息:" + sha1);
sign = sha1;
return sha1;
}
/// <summary>
/// Post
/// </summary>
/// <param name="path"></param>
/// <param name="jsondata"></param>
/// <param name="actionResult"></param>
public IEnumerator Post(string path, string jsondata, Action<string> actionResult)
{
byte[] databyte = null;
if (jsondata != null)
{
databyte = Encoding.UTF8.GetBytes(jsondata);
}
using (UnityWebRequest _request = new UnityWebRequest(path, UnityWebRequest.kHttpVerbPOST))
{
if (jsondata != null)
_request.uploadHandler = new UploadHandlerRaw(databyte);
_request.downloadHandler = new DownloadHandlerBuffer();
_request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
if (token != null)
{
Debug.Log("token:" + token);
_request.SetRequestHeader("token", token);
}
_request.timeout = 60;
UnityWebRequestAsyncOperation op = _request.SendWebRequest();
yield return op;
while (!op.isDone)
{
yield return null;
}
string result = "";
if (op.webRequest.isHttpError || op.webRequest.isNetworkError)
{
Debug.Log("Get web resource failed: " + path);
Debug.Log("ErrorCode: " + op.webRequest.responseCode+" "+op.webRequest.error);
}
else
{
result = op.webRequest.downloadHandler.text;
}
result = Regex.Unescape(result);
actionResult?.Invoke(result);
}
}
public void PostLogin(){
LoginSignDir(out string loginSignPostMessage);
StartCoroutine(Post(UrlPath + LoginUrl, loginSignPostMessage, g =>
{
Debug.Log(g);
JObject obj = JObject.Parse(g);
JToken _token = obj["data"]["token"];
token = _token.ToString();
Debug.Log("token:" + token);
}));
}
public void GetListPost(){
StartCoroutine(Post(UrlPath + GetListUrl, null, g =>
{
Debug.Log(g);
}));
}
HandJsonFormat 是把字典输出成json字符串格式。
public static string HandJsonFormat(this Dictionary<string, object> source)
{
string json = "{";
foreach (KeyValuePair<string, object> pair in source)
{
string key = pair.Key;
object value = pair.Value;
json += "\"" + key + "\":";
if (value is string)
{
json += "\"" + value + "\"";
}
else if (value is int || value is float || value is double || value is Int64)
{
json += value.ToString();
}
else if (value is bool)
{
json += ((bool)value) ? "true" : "false";
}
else
{
throw new ArgumentException("Unsupported value type: " + value.GetType());
}
json += ",";
}
if (json.EndsWith(","))
{
json = json.Remove(json.Length - 1);
}
json += "}";
return json;
}
A Native Collection has not been disposed, resulting in a memoryleak. Enable Full StackTraces to get more details.文章来源:https://www.toymoban.com/news/detail-805725.html
这里面有个坑,UnityWebRequest如果不用using块包住,不会自动调用方法释放,可能会导致报错内存泄漏的报错。
当然,你也可以在协程中自己手动释放。文章来源地址https://www.toymoban.com/news/detail-805725.html
到了这里,关于Unity 与后端通信,对接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!