Programming/Unity

[Unity] UniRx - WWW 통신을 Reactive하게 관리하자 (ObservableWWW)

HyeunJae 2022. 5. 10. 23:12

 

설명의 앞서 UniRx 라이브러리의 ObservableWWW 는 obsolete 된 WWW 클래스를 사용하고 있습니다.
따라서 Unity에서 사용을 권장하는 UnityWebRequest를 사용하면 좋은데 이를 위해 UniRx 제작자가 만든 UniTask 라이브러리를 추천합니다.
이밖에도 강력한 비동기 기능들을 지원한다고 합니다.

Cysharp/UniTask: Provides an efficient allocation free async/await integration for Unity. (github.com)

 

GitHub - Cysharp/UniTask: Provides an efficient allocation free async/await integration for Unity.

Provides an efficient allocation free async/await integration for Unity. - GitHub - Cysharp/UniTask: Provides an efficient allocation free async/await integration for Unity.

github.com

 


 

 

UniRx.ObservableWWW 클래스

정의

WWW 클래스를 기반으로 한  UniRx 통신 클래스이다.

내부 로직은 Coroutine으로 동작한다.

 

네임 스페이스 선언

using UniRx;

ObservableWWW.Get(string url, Hash headers = null, IProgress<float> progress = null)

- 해당 url 로 Get 전송

- 반환 값으로 IObservable<string> 리턴 (Subscribe, ToYieldInstruction 등 Rx 관련 사용 가능)

 

GetAndGetBytes(string url, Hash headers = null, IProgress<float> progress = null)

- 해당 url로 Get 전송

- 반환 값으로 IObservable<byte[]> 리턴 (결과값을 Byte 배열로 리턴됨)

 

 GetWWW(string url, Hash headers = null, IProgress<float> progress = null)

- 해당 url로 Get 전송

- 반환 값으로 IObservable<WWW> 리턴

 

 

Post(string url, byte[] postData, IProgress<float> progress = null)

- 해당 url로 Post 전송

 

 

 

응용

using System.Collections;
using System.Collections.Generic;
using System.Text;

using UnityEngine;
using UnityEngine.Networking;

using UniRx;
using UniRx.Triggers;

public class RxWWW : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(nameof(CoWWWExample));
    }

    IEnumerator CoWWWExample()
    {
        var obsWWWRequest = ObservableWWW.Get("http://google.com/"); 
        obsWWWRequest.Subscribe(content => Debug.Log(content));

        yield return Observable.WhenAll(obsWWWRequest).ToYieldInstruction();

        var obsWWWRequest2 = ObservableWWW.GetAndGetBytes("http://google.com");
        obsWWWRequest2.Subscribe(contentBytes => Debug.Log(Encoding.UTF8.GetString(contentBytes)));

        yield return Observable.WhenAll(obsWWWRequest2).ToYieldInstruction();

        var wwwRequest = ObservableWWW.GetWWW("http://google.com/");
        wwwRequest.Subscribe(www => Debug.Log(www.text));

        yield return Observable.WhenAll(wwwRequest).ToYieldInstruction();

        var progressNotifier = new ScheduledNotifier<float>();
        progressNotifier.Subscribe(x => Debug.Log($"progress : {x}")); // write www.progress

        // pass notifier to WWW.Get/Post
        var progressRequest = ObservableWWW.Get("http://google.com/", progress: progressNotifier);
        progressRequest.Subscribe(conteent => Debug.Log(conteent));

        yield return Observable.WhenAll(progressRequest).ToYieldInstruction();

        ObservableWWW.Get("http://google.com/404")
            .CatchIgnore((WWWErrorException ex) => 
            {
                Debug.Log(ex.RawErrorMessage);
                if (ex.HasResponse)
                {
                    Debug.Log(ex.StatusCode);
                }
            }).Subscribe(content => { Debug.Log(content); });
    }
}