12/08/2018, 14:04

UnityWebRequest (phần 2)

3.4 Send form lên HTTP Server (POST) Có 2 method chính để send data lên server, format giống như một HTML Form: - Method hợp lệ: sử dụng WWWForm Để giúp di chuyển từ hệ thống WWW cũ, hệ thống UnityWebRequest mới cho phép bạn sử dụng các đối tượng WWWForm cũ để cung cấp dữ liệu mẫu.Trong trường ...

3.4 Send form lên HTTP Server (POST)

Có 2 method chính để send data lên server, format giống như một HTML Form: - Method hợp lệ: sử dụng WWWForm Để giúp di chuyển từ hệ thống WWW cũ, hệ thống UnityWebRequest mới cho phép bạn sử dụng các đối tượng WWWForm cũ để cung cấp dữ liệu mẫu.Trong trường hợp này, function là:

WebRequest.Post(string url, WWWForm formData);

Chi tiết:

Phương pháp này tạo ra một UnityWebRequest mới và đặt URL target với giá trị string argument đầu tiên. Nó có thể đọc bất cứ custom header được tạo ra bởi các đối số WWWForm (như Content-Type) và sao chép chúng vào UnityWebRequest. Phương pháp này, theo mặc định, gắn một DownloadHandlerBuffer đến UnityWebRequest. Bạn có thể sử dụng để kiểm tra reply của máy chủ.

Phương pháp này đọc dữ liệu thô được tạo ra bởi các đối tượng WWWForm và buffer nó trong một đối tượng UploadHandlerRaw, kèm theo đó là các UnityWebRequest. Do đó, những thay đổi trong WWWFormobject sau khi gọi UnityWebRequest.POST sẽ không làm thay đổi nội dung của UnityWebRequest. Ví dụ:

using UnityEngine;
using System.Collections;

class MyBehavior: public MonoBehaviour {
    void Start() {
        StartCoroutine(Upload());
    }

    IEnumerator Upload() {
        WWWForm form = new WWWForm();
        form.AddField("myField", "myData");

        UnityWebRequest www = UnityWebRequest.Post("http://www.my-server.com/myform", form);
        yield return www.Send();

        if(www.isError) {
            Debug.Log(www.error);
        }
        else {
            Debug.Log("Form upload complete!");
        }
    }
}
  • Phương thức mới: sử dụng IMultipartFormSection

Để kiểm soát nhiều hơn cách bạn định dạng dữ liệu, UnityWebRequestsystem chứa một giao diện IMultipartFormSection (người sử dụng implement được). Đối với các ứng dụng tiêu chuẩn, Unity cũng cung cấp những implementation mặc định cho dữ liệu và các phần file: MultipartFormDataSection và MultipartFormFileSection.

Để chấp nhận tình trạng quá tải của UnityWebRequest.POST, như một tham số thứ hai, một argument List, mà các member đều phải được IMultipartFormSections. Function là:

WebRequest.Post(string url, List<IMultipartFormSection> formSections);

Cụ thể:

Phương pháp này tạo ra một UnityWebRequest và đặt URL target tới các tham số string đầu tiên. Nó cũng đặt header Content-Type của UnityWebRequest thích hợp cho các dữ liệu form quy định trong danh sách các đối tượng IMultipartFormSection. Phương pháp này, theo mặc định, gắn một DownloadHandlerBuffer đến UnityWebRequest. Để thuận tiện việc bạn có thể kiểm tra trả lời của máy chủ. Tương tự như các phương pháp WWWForm POST, phương pháp HLAPI này sẽ gọi IMultipartFormSection cung cấp lần lượt, và định dạng chúng thành một dạng nhiều phần tiêu chuẩn như quy định trong RFC 2616.

Các dữ liệu mẫu định dạng sẵn sẽ được lưu trữ trong một đối tượng UploadHandlerRaw tiêu chuẩn, sau đó được gắn vào UnityWebRequest. Kết quả là, những thay đổi cho các đối tượng IMultipartFormSection thực hiện sau khi các cuộc gọi UnityWebRequest.POST sẽ không được reflect trong các dữ liệu đến máy chủ.

VÍ dụ:

using UnityEngine;
using System.Collections;

class MyBehavior: public MonoBehaviour {
    void Start() {
        StartCoroutine(Upload());
    }

    IEnumerator Upload() {
        List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
        formData.Add( new MultipartFormDataSection("field1=foo&field2=bar") );
        formData.Add( new MultipartFormFileSection("my file data", "myfile.txt") );

        UnityWebRequest www = UnityWebRequest.Post("http://www.my-server.com/myform", formData);
        yield return www.Send();

        if(www.isError) {
            Debug.Log(www.error);
        }
        else {
            Debug.Log("Form upload complete!");
        }
    }
}

3.5 Upload raw data lên HTTP Server (PUT)

Một số ứng dụng web hiện đại thích rằng các tập tin được tải lên thông qua HTTP PUT. Đối với kịch bản này, Unity cung cấp các phương pháp UnityWebRequest.PUT. Phương pháp này có hai argument. Argument đầu tiên là một string quy định các URL target tới request. Argument thứ hai có thể là một string hoặc một mảng byte, và xác định payload data được gửi đến server.

Function là:

WebRequest.Put(string url, string data);
WebRequest.Put(string url, byte[] data);

Cụ thể:

Phương pháp này tạo một UnityWebRequest và set content-type là application / octet-stream. Phương pháp này gắn một DownloadHandlerBuffer tiêu chuẩn đến các UnityWebRequest. Như với các phương pháp POST, bạn có thể sử dụng nó để trả lại dữ liệu kết quả từ các ứng dụng của bạn.

Phương pháp này lưu trữ các dữ liệu tải lên vào trong một đối tượng UploadHandlerRaw chuẩn và gắn nó vào UnityWebRequest. Kết quả là, nếu sử dụng các method byte [], thay đổi mảng byte thực hiện sau khi các cuộc gọi UnityWebRequest.PUT sẽ không được reflect trong các dữ liệu tải lên server.

Ví dụ:

using UnityEngine;
using System.Collections;

class MyBehavior: public MonoBehaviour {
    void Start() {
        StartCoroutine(Upload());
    }

    IEnumerator Upload() {
        byte[] myData = System.Text.Encoding.UTF8.GetBytes("This is some test data");
        UnityWebRequest www = UnityWebRequest.Put("http://www.my-server.com/upload", myData);
        yield return www.Send();

        if(www.isError) {
            Debug.Log(www.error);
        }
        else {
            Debug.Log("Upload complete!");
        }
    }
}
  1. Finer Control: sử dụng LLAPI

Trong khi HLAPI được thiết kế để giảm thiểu mã boilerplate, các LLAPI được thiết kế để cho phép sự linh hoạt tối đa. Nói chung, bằng cách sử dụng liên quan đến việc tạo ra LLAPI UnityWebRequests, sau đó tạo ra DownloadHandlers hoặc UploadHandlers thích hợp và gắn chúng vào UnityWebRequests của bạn.

Lưu ý: Các HLAPI và LLAPI không loại trừ lẫn nhau. Bạn luôn có thể tùy chỉnh các đối tượng UnityWebRequest tạo thông qua HLAPI nếu bạn cần để tinh chỉnh một script phổ biến. 4.1 Tạo UnityWebRequests

WebRequests có thể chỉ cần khởi tạo như bất kỳ đối tượng khác. Hai constructor có sẵn. Các tiêu chuẩn, constructor không tham số tạo ra một UnityWebRequest mới với tất cả các thiết lập mặc định hoặc để trống: * URL mục tiêu không được thiết lập * Không có custom header được thiết lập * Giới hạn chuyển hướng được thiết lập đến 32

Các constructor thứ hai có một đối số chuỗi. Nó gán URL mục tiêu của UnityWebRequest với giá trị của các đối số chuỗi, và nó không giống với các constructor không tham số. Ví dụ:

UnityWebRequest wr = new UnityWebRequest(); // Completely blank
UnityWebRequest wr2 = new UnityWebRequest("http://www.mysite.com"); // Target URL is set

4.2 Tạo UploadHandlers

Hiện nay, chỉ có một loại upload handler có sẵn: UploadHandlerRaw. lớp này chấp nhận một bộ đệm dữ liệu vào thời điểm xây dựng. Buffer này được sao chép vào bộ nhớ native-code và sau đó được sử dụng bởi hệ thống UnityWebRequest khi remote server đã sẵn sàng để chấp nhận body data.

Handlers tải lên cũng chấp nhận một content type là string. Chuỗi này sẽ được sử dụng cho các giá trị của Content-Type header của UnityWebRequest nếu bạn không tự đặt header Content-Type trên UnityWebRequest. Nếu bạn tự thiết lập một header Content-Type vào đối tượng UnityWebRequest, sau đó các Content-Type của Upload Handler sẽ bị bỏ qua. Nếu bạn không đặt một Content-Type vào hoặc là UnityWebRequest hoặc UploadHandler, sau đó hệ thống sẽ mặc định để thiết lập một Content-Type là application/octet-stream. Ví du:

byte[] payload = new byte[1024];
// ... fill payload with data ...

UnityWebRequest wr = new UnityWebRequest("http://www.mysite.com/data-upload");
UploadHandler uploader = new UploadHandlerRaw(payload);

// Will send header: "Content-Type: custom/content-type";
uploader.contentType = "custom/content-type";

wr.uploadHandler = uploader;

4.3 Tạo DownloadHandlers

Hiện nay, có bốn loại DownloadHandlers:

  • các store DownloadHandlerBuffer nhận được dữ liệu trong một byte buffer native-code, và quyền truy cập hoặc là để các byte thô hoặc sẽ chuyển đổi nó thành một chuỗi UTF8.
  • các store DownloadHandlerTexture nhận được dữ liệu trong một UnityEngine.Texture. Sau khi hoàn tất download, nó sẽ giải mã hình ảnh JPEG và PNG vào các đối tượng UnityEngine.Texture hợp lệ. Chỉ có một bản sao của UnityEngine.Texture sẽ được tạo ra cho mỗi đối tượng DownloadHandlerTexture, mà sẽ làm giảm hiệu suất từ garbage collection.
  • DownloadHandlerAssetBundle stream nhận dữ liệu vào hệ thống asset bundle của Unity. Một khi hệ thống asset bundle đã nhận đủ dữ liệu, asset bundle sẽ có sẵn như là một đối tượng UnityEngine.AssetBundle. Như trên, chỉ có một bản sao của đối tượng UnityEngine.AssetBundle sẽ được tạo ra để giảm thiểu tác động tới memory.
  • DownloadHandlerScript là một class đặc biệt. Trong class của nó, nó sẽ không làm gì cả. Tuy nhiên, class này có thể được thừa kế bởi một class người dùng định nghĩa. Class này sẽ nhận được callbacks từ hệ thống UnityWebRequest, mà sau đó có thể được sử dụng để thực hiện việc xử lý hoàn toàn tùy chỉnh của dữ liệu khi nó đến từ mạng.

Một Download Handler chuyên cho Audio Clip cũng có sẵn. Các API này tương tự như giao diện của DownloadHandlerTexture.

Các ví dụ:

DownloadHandlerBuffer:

using UnityEngine;
using System.Collections;

class MyBehaviour: public MonoBehaviour {
    void Start() {
        StartCoroutine(GetText());
    }

    IEnumerator GetText() {
        UnityWebRequest www = new UnityWebRequest("http://www.my-server.com");
        www.downloadHandler = new DownloadHandlerBuffer();
        yield return www.Send();

        if(www.isError) {
            Debug.Log(www.error);
        }
        else {
            // Show results as text
            Debug.Log(www.downloadHandler.text);

            // Or retrieve results as binary data
            byte[] results = www.downloadHandler.data;
        }
    }
}

DownloadHandlerTexture

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
[RequireComponent(typeof(UnityEngine.UI.Image))]
public class ImageDownloader : MonoBehaviour {
    UnityEngine.UI.Image _img;

    void Start () {
        _img = GetComponent<UnityEngine.UI.Image>();
        Download("http://www.mysite.com/myimage.png");
    }

    public void Download(string url) {
        StartCoroutine(LoadFromWeb(url));
    }

    IEnumerator LoadFromWeb(string url)
    {
        UnityWebRequest wr = new UnityWebRequest(url);
        DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
        wr.downloadHandler = texDl;
        yield return wr.Send();
        if(!wr.isError) {
            Texture2D t = texDl.texture;
            Sprite s = Sprite.Create(t, new Rect(0, 0, t.awidth, t.height),
                                     Vector2.zero, 1f);
            _img.sprite = s;
        }
    }
}
0