Unity 与后端通信,对接口

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.

这里面有个坑,UnityWebRequest如果不用using块包住,不会自动调用方法释放,可能会导致报错内存泄漏的报错。
当然,你也可以在协程中自己手动释放。

猜你喜欢

转载自blog.csdn.net/weixin_44347839/article/details/134926173
今日推荐