Docking record of Rapeseed Http protocol based on Unity

Due to the needs of the company's business, the docking work of the Http protocol interface was carried out with "Rape Flower".
This is the first time to connect to the Http protocol completely independently, and it is also the first time to connect to an external protocol, so the main key points and pitfalls encountered in the process are recorded here. Leave it for future inquiries.


1. Decimal type data and precision issues

This is the first time that decimal type data is actually used. Generally speaking, this type has high precision and is suitable for financial and monetary calculations. For details, please refer to this article .
The reason for mentioning Decimal here is mainly because of stepping on a pit, which is also related to the serialization operation during Jsonization. The Newtonsoft
plug-in is used for the serialization operation here instead of Unity's own . The reason is that it seems that cannot support this type of data, and if the type is used, there will be a serious loss of precision. For example, when a data is being processed After serialization, a result like this may be displayed. However, although the use of Decimal type data can solve the problem of precision, there is still a more difficult problem, that is, when serializing, Decimal retains at least one decimal by default, that is to say, even if it is an integer, after serialization Also displayed as . The problem is that due to the need for signature encryption, this Decimal type data performs an operation, and the style displayed after is guaranteed to be the same as the style displayed in serialization. Questions are as follows:JsonUtilityJsonUtilityDecimalFloat1.0f0.9998641
5m5.0
ToString()ToString()

decimal a = 5M;
Debug.Log(a.ToString()); 		// 显示结果为 5
Debug.Log(a.ToString("#.#"));	// 显示结果为 5.0 但是遇到 a = 1.23 的情况也只能显示 1.2

Solution:

// 对 Decimal 进行扩展
public static class DeciamlExtension
{
    
    
    /// <summary>
    /// Decimal 扩展方法
    /// 由于 Decimal 在转换为 json 格式时默认至少保留 1 位小数,
    /// 例如:decimal num = 1 在转换成 json 后就是 1.0
    /// 为了在 ToString 时和 json 保持一致,添加此扩展方法
    /// </summary>
    /// <param name="data"></param>
    /// <param name="scale"></param>
    /// <returns></returns>
    public static string ToString_JsonStyle(this decimal data)
    {
    
    
        string strData = data.ToString();
		// 获取小数点的位置,当无法获取到小数点时即数据为整数时,index = -1
        int index = strData.IndexOf(".");
        // 获取数据的总长度
        int dataLength = strData.Length;

        if (index != -1)
        {
    
    
        	// 对小数点前后的数字进行重新拼接
            return string.Format("{0}.{1}", strData.Substring(0, index), strData.Substring(index + 1, dataLength - index - 1));
        }
        else
        {
    
    
        	// 当小数点不存在时,默认显示小数点后一位
            return string.Format("{0}.0", strData);
        }

    }
}

2. About how to get the 13-bit timestamp

The timestamp obtained by taking the value to milliseconds is 13 digits, and if only seconds are obtained, the timestamp is 10 digits. Generally a system will take either 13 bits or 10 bits.

Timestamp : Timestamp refers to the total number of seconds from 00:00:00 on January 01, 1970, Greenwich Mean Time (08:00:00, January 01, 1970, Beijing time) to the present. In layman's terms, a timestamp is a complete and verifiable piece of data that can indicate that a piece of data has existed at a specific point in time. Its proposal is mainly to provide users with an electronic evidence to prove the generation time of certain data of users. In practical applications, it can be used in various aspects including e-commerce and financial activities, and especially can be used to support the "non-repudiation" service of public key infrastructure.

1 second = 1000 milliseconds
1 millisecond = 1000 microseconds
1 microsecond = 1000 nanoseconds
1 millisecond = 1000000 nanoseconds

DateTime.Ticks represents the number of 100 nanoseconds elapsed since 12:00:00 midnight on January 1, 0001, that is, the property of Ticks is 100 nanoseconds (1 Ticks = 0.0001 milliseconds).

// 设置初始时间
public DateTime StartTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
// 获取 13 位时间戳
public string GetTimeStamp()
{
    
    
	// 获取当前时间
	DateTime endTime = System.DateTime.UtcNow;
	// 获取时间差值(时间戳)
	TimeSpan timeSpan = endTime - StartTime;
	// 返回 13 位时间戳
	return (timeSpan.Ticks / 10000).ToString();
}

3. Use Json type data for Http Post access

Http has a variety of request methods , and we need to use the Post method to access.

Based on the latest version of Unity, the use of the WWW class has been abandoned and replaced by the more advanced UnityWebRequest.

Special attention should be paid to the setting of the http response header information. For this, please refer to the contents of the "HTTP response header information" and "HTTP content-type" to understand.

For now, the default setting of this response header in Unity seems to be like SetRequestHeader("Content-Type", "application/json;charset=utf-8");this. After checking a few materials, it is basically this setting method, and at most some will charset=utf-8remove it SetRequestHeader("Content-Type", "application/json");. Or is it usually set like this?

However, after some data review, it is found that this specific setting method may also be related to the configuration on the server side, and certain coordination is required. At least we have no problem using this configuration this time.

The complete code is as follows:

 	/// <summary>
    /// Http 使用 Post 方式请求
    /// </summary>
    /// <param name="url"></param>
    /// <param name="json"></param>
    /// <param name="callback"></param>
    public void SendPostRequest(string url, string json, Action<string> callback)
    {
    
    
        StartCoroutine(HttpPostRequest(url, json, callback));
    }

	// 使用协程调用 UnityWebRequest 进行 Http 通信
    private IEnumerator HttpPostRequest(string url, string json, Action<string> callback)
    {
    
    
    	// 将需要提交的数据转换为 UTF-8 编码的 byte 数组
        byte[] dataBody = Encoding.UTF8.GetBytes(json);
		// 创建 UnityWebRequest 实例
		// 使用 using 关键字,可以让程序在结束任务后自动释放 UnityWebRequest 实例,防止内存泄漏
        using (UnityWebRequest unityWebRequest = new UnityWebRequest(url, "POST"))
        {
    
    
            // UploadHander 用于控制数据的上传
            unityWebRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(dataBody);

            // 设置 http 响应头信息
            unityWebRequest.SetRequestHeader("Content-Type", "application/json;charset=utf-8");

            // DownloadHander 用于控制数据的下载
            unityWebRequest.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();

            // 正式发送 http 请求
            yield return unityWebRequest.SendWebRequest();

            if (unityWebRequest.isHttpError || unityWebRequest.isNetworkError)
            {
    
    
                if (callback != null) callback(unityWebRequest.downloadHandler.text);
                Debug.LogError("Http Error: " + unityWebRequest.error + "\n" + unityWebRequest.downloadHandler.text);
            }
            else
            {
    
    
                if (unityWebRequest.isDone)
                {
    
    
                    if (callback != null) callback(unityWebRequest.downloadHandler.text);
                }
                else
                {
    
    
                    Debug.LogError("Http 请求失败: " + unityWebRequest.error);
                }
            }
        }
    }

4. About the Http connection problem of Android Q (Android 10)

After printing out the test package, the following problems will occur when installing to the real Android device:

Cleartext HTTP traffic to xxx.xxx.xxx.xx not permitted

where xxx.xxx.xxx.xxis the requested http url address.

After querying, it was found that this problem began to appear after Android 9 (Android P). In order to ensure the security of user data and devices, Google's applications for the Android system (versions after Android P) will require encrypted connections by default, while http network requests use unencrypted plaintext traffic.

There are several solutions available: check out this article .

Here is a relatively simple and crude method:

<application>Add the following content to the tag of the AndroidManifest.xml configuration file

	android:usesCleartextTraffic="true

android:usesCleartextTrafficIndicates whether the application intends to use cleartext network traffic, such as cleartext HTTP. The default value is "true" for applications targeting API level 27 or lower. Defaults to "false" for apps targeting API level 28 or higher.

When the property is set to "false", platform components (for example, HTTP and FTP stacks, DownloadManager and MediaPlayer) will deny applications' requests to use cleartext traffic. It is strongly recommended that third-party libraries adopt this setting as well. The main reason for avoiding clear text communication is the lack of confidentiality, authenticity and tamper protection; cyber attackers can eavesdrop on the transmitted data and also modify it without being detected.


So far, the more important issues have been reviewed.

Guess you like

Origin blog.csdn.net/EverNess010/article/details/108648351