Unity network communication-simple encapsulation of HttpRestful requests

To implement the encapsulation of Http requests, we mainly consider two issues:

  1. All network communications are written in a class, and external calls only consider incoming parameters to achieve a decoupling effect
  2. Unity’s communication uses coroutine to realize network communication. How to handle the subsequent operations of the value returned by the communication

Normal encapsulation of the first question will take this into consideration, so I won’t go into it here. The main thing we consider is the second question. Because network communication is handled through coroutines, it is impossible to achieve our normal encapsulation and only method returns. It is implemented by value, so what should be used here is to pass in the callback function. So in this article we use Action to solve this problem.

Code

Micro Card Smart Enjoyment

01

Organize code scripts

We created a Model folder (to store object classes) and a Utils folder (to store tool classes) under Scripts, then moved the WeatherForecase class to Model, and created a Network folder under the Utils folder. Used to handle network communications, and then create an HttpRestful C# script in this folder.

02

HttpRestful encapsulation

Define a static instance, and then write the corresponding instance method to get the method.

Write the coroutine method call of Get. The last parameter is the method of Action. The first parameter of Action is bool, which is used to return the success or failure of the communication. The second parameter string is the return value. communication information.

The parameters passed in to the externally called Get method are the same, and the internal one is the direct account opening coroutine operation. The following Post implementation is also written according to this idea, except that the data we passed in needs to be added to the incoming parameters.

HttpRestful complete code

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class HttpRestful : MonoBehaviour
{
    private static HttpRestful _instance;

    public static HttpRestful Instance
    {
        get
        {
            if(_instance == null)
            {
                GameObject goRestful = new GameObject("HttpRestful");
                _instance = goRestful.AddComponent<HttpRestful>();
            }
            return _instance;
        }
    }

    #region Get request
    /// <summary>
    /// Get request
    /// </summary>
    /// <param name="url"></param>
    /// <param name="actionResult"></param>
    public void Get(string url, Action<bool, string> actionResult = null)
    {
        StartCoroutine(_Get(url, actionResult));
    }

    private IEnumerator _Get(string url, Action<bool, string> action)
    {
        using (UnityWebRequest request = UnityWebRequest.Get(url))
        {
            yield return request.SendWebRequest();

            string resstr = "";
            if (request.isNetworkError || request.isHttpError)
            {
                resstr = request.error;
            }
            else
            {
                resstr = request.downloadHandler.text;
            }

            if (action != null)
            {
                action(request.isHttpError, resstr);
            }
        }
    }
    #endregion


    #region POST request
    public void Post(string url, string data, Action<bool, string> actionResult = null)
    {
        StartCoroutine(_Post(url, data, actionResult));
    }

    private IEnumerator _Post(string url, string data, Action<bool, string> action)
    {
        using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(data));
            request.SetRequestHeader("content-type", "application/json;charset=utf-8");
            request.downloadHandler = new DownloadHandlerBuffer();

            yield return request.SendWebRequest();

            string resstr = "";
            if (request.isNetworkError || request.isHttpError)
            {
                resstr = request.error;
            }
            else
            {
                resstr = request.downloadHandler.text;
            }

            if (action != null)
            {
                action(request.isHttpError, resstr);
            }
        }
    }
    #endregion
}

copy

03

CallHttpRestful

We copied a UIScripts again, and then added Old after one of the names, so that we don’t need to reset it again. We can directly modify it in the UIScripts script.

First define an Action, where the parameters are the same as the Action method passed in HttpRestful.

Then add an InitAction method and write its implementation method for the defined actionRes. The method is to directly display the text if the communication fails, process it after success, and then display the processed data, because the data type returned after the Get and Post calls are the same, so if we write an Action here, we can call this method. subsequent data processing.

Then we first call the initialization Action in Start, and then use

HttpRestful.Instance.Get(url, actionRes);
HttpRestful.Instance.Post(url, json, actionRes);

copy

You can directly process the data, and delete the remaining methods we called yesterday.

UIScipts complete code

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class UIScripts : MonoBehaviour
{
    [Header("Button")]
    public Button btnget;
    public Button btngetparm;
    public Button btnjson;
    public Button btnpost;

    [Space]
    [Header("display")]
    public Text txtshow;

    [Space]
    [Header("input box")]
    public InputField edturl;
    public InputField edtparm;

    //Define an Action that returns data
    private Action<bool, string> actionRes;
    // Start is called before the first frame update
    void Start()
    {
        InitAction();

        //Get button operation
        btnget.onClick.AddListener(() =>
        {
            Debug.Log(edturl.text);
            string url = edturl.text;
            HttpRestful.Instance.Get(url, actionRes);
        });
        btngetparm.onClick.AddListener(() =>
        {
            string url = edturl.text;
            string param = edtparm.text;

            string allurl = url + "/Info?Summary=" + param;
            HttpRestful.Instance.Get(allurl, actionRes);
        });

        btnjson.onClick.AddListener(() => StartCoroutine(JsonConvert()));

        btnpost.onClick.AddListener(() =>
        {
            WeatherForecast item = new WeatherForecast();
            item.Summary = "Alvin";
            item.Date = DateTime.Now;
            item.TemperatureC = 10;
            item.TemperatureF = 20;
            string json = JsonUtility.ToJson(item);

            string url = edturl.text + "/Reg";
            Debug.Log(url);
            HttpRestful.Instance.Post(url, json, actionRes);
        });
    }

    /// <summary>
    /// Write the processing method that returns Action
    /// </summary>
    private void InitAction()
    {
        actionRes = new Action<bool, string>((bl, str) =>
        {
            if(bl)
            {
                txtshow.text = str;
            }
            else
            {
                string resjson = "{"array":" + str + "}";
                txtshow.text = resjson;
                WeatherData lists = JsonUtility.FromJson<WeatherData>(resjson);
                StringBuilder sb = new StringBuilder();
                foreach (WeatherForecast item in lists.array)
                {
                    sb.Append("Date:" + item.Date + " Summary:" + item.Summary + " TemperatureF:"
                         + item.TemperatureF + "TemperatureC:" + item.TemperatureC + "\r\\
");
                }
                txtshow.text = sb.ToString();
            }
        });
    }

    IEnumeratorJsonConvert()
    {
        WeatherForecast item = new WeatherForecast();
        item.Summary = "Alvin";
        item.Date = DateTime.Now;
        item.TemperatureC = 10;
        item.TemperatureF = 20;

        string json = JsonUtility.ToJson(item);
        txtshow.text = json;
        yield return new WaitForSeconds(3f);

        WeatherForecast newitem = JsonUtility.FromJson<WeatherForecast>(json);
        string showtext = "Summary:" + newitem.Summary + "Date:" + newitem.Date +
            " C:" + newitem.TemperatureC + " F:" + newitem.TemperatureF;
        txtshow.text = showtext;
    }
}

copy

achieve effect

The picture above shows the effect of calling WebApi after encapsulation. Later I compiled it under the Android platform, and there was no problem with the call. This method can be used across platforms.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Network skill treeProtocol supporting applicationsHTTP protocol 41584 people are learning the system