UniRX网络请求 Http篇 get post

mac2025-02-11  12

UniRX网络请求 Http篇 get post

前言:unity高版本之后UniRX对于ObservableWWW已经弃用 在网上搜索了一下 结果一个老外具体叫什么忘记了 自己重新对UnityWebRequest封装了一份ObservableWebRequest

具体封装脚本: 这个脚本之前只支持Post以字典方式请求,自己又改了一下 支持Post Json格式请求

using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using UniRx; using UnityEngine; using UnityEngine.Networking; #if !UniRxLibrary using ObservableUnity = UniRx.Observable; #endif namespace UniRx.WebRequest { public static class ObservableWebRequest { public static IObservable<UnityWebRequest> ToRequestObservable(this UnityWebRequest request, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<UnityWebRequest>((observer, cancellation) => Fetch(request, null, observer, progress, cancellation)); } public static IObservable<string> ToObservable(this UnityWebRequest request, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(request, null, observer, progress, cancellation)); } public static IObservable<byte[]> ToBytesObservable(this UnityWebRequest request, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => Fetch(request, null, observer, progress, cancellation)); } public static IObservable<string> Get(string url, IDictionary<string, string> headers = null, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<string>( (observer, cancellation) => FetchText(UnityWebRequest.Get(url), headers, observer, progress, cancellation)); } public static IObservable<byte[]> GetAndGetBytes(string url, IDictionary<string, string> headers = null, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(UnityWebRequest.Get(url), headers, observer, progress, cancellation)); } public static IObservable<UnityWebRequest> GetRequest(string url, IDictionary<string, string> headers = null, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<UnityWebRequest>((observer, cancellation) => Fetch(UnityWebRequest.Get(url), headers, observer, progress, cancellation)); } public static IObservable<string> Post(string url, Dictionary<string, string> postData, IDictionary<string, string> headers = null, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(UnityWebRequest.Post(url, postData), headers, observer, progress, cancellation)); } public static IObservable<string> PostJson(string url,string json, IDictionary<string, string> headers = null, IProgress<float> progress = null) { var request = new UnityWebRequest(url, "POST"); var bodyByte= Encoding.UTF8.GetBytes(json); request.uploadHandler=new UploadHandlerRaw(bodyByte); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type","application/json"); return ObservableUnity.FromCoroutine<string>((observer, cancellation) => FetchText(request, headers, observer, progress, cancellation)); } public static IObservable<byte[]> PostAndGetBytes(string url, Dictionary<string, string> postData, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(UnityWebRequest.Post(url, postData), null, observer, progress, cancellation)); } public static IObservable<byte[]> PostAndGetBytes(string url, Dictionary<string, string> postData, IDictionary<string, string> headers, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<byte[]>((observer, cancellation) => FetchBytes(UnityWebRequest.Post(url, postData), headers, observer, progress, cancellation)); } public static IObservable<UnityWebRequest> PostRequest(string url, Dictionary<string, string> postData, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<UnityWebRequest>((observer, cancellation) => Fetch(UnityWebRequest.Post(url, postData), null, observer, progress, cancellation)); } public static IObservable<UnityWebRequest> PostRequest(string url, Dictionary<string, string> postData, IDictionary<string, string> headers, IProgress<float> progress = null) { return ObservableUnity.FromCoroutine<UnityWebRequest>((observer, cancellation) => Fetch(UnityWebRequest.Post(url, postData), headers, observer, progress, cancellation)); } public static IObservable<AssetBundle> LoadFromCacheOrDownload(string url, uint version, uint crc, IProgress<float> progress = null) { return null;// ObservableUnity.FromCoroutine<AssetBundle>((observer, cancellation) => FetchAssetBundle(UnityWebRequest.GetAssetBundle(url, version, crc),null, observer, progress, cancellation)); } static IEnumerator Fetch<T>(UnityWebRequest request, IDictionary<string, string> headers, IObserver<T> observer, IProgress<float> reportProgress, CancellationToken cancel) { if (headers != null) { foreach (var header in headers) { request.SetRequestHeader(header.Key, header.Value); } } if (reportProgress != null) { var operation = request.SendWebRequest(); while (!operation.isDone && !cancel.IsCancellationRequested) { try { reportProgress.Report(operation.progress); } catch (Exception ex) { observer.OnError(ex); yield break; } yield return null; } } else { yield return request.SendWebRequest(); } if (cancel.IsCancellationRequested) { yield break; } if (reportProgress != null) { try { reportProgress.Report(request.downloadProgress); } catch (Exception ex) { observer.OnError(ex); yield break; } } } static IEnumerator FetchRequest(UnityWebRequest request, IDictionary<string, string> headers, IObserver<UnityWebRequest> observer, IProgress<float> reportProgress, CancellationToken cancel) { using (request) { yield return Fetch(request, headers, observer, reportProgress, cancel); if (cancel.IsCancellationRequested) { yield break; } if (!string.IsNullOrEmpty(request.error)) { observer.OnError(new UnityWebRequestErrorException(request)); } else { observer.OnNext(request); observer.OnCompleted(); } } } static IEnumerator FetchText(UnityWebRequest request, IDictionary<string, string> headers, IObserver<string> observer, IProgress<float> reportProgress, CancellationToken cancel) { using (request) { yield return Fetch(request, headers, observer, reportProgress, cancel); if (cancel.IsCancellationRequested) { yield break; } if (!string.IsNullOrEmpty(request.error)) { observer.OnError(new UnityWebRequestErrorException(request)); } else { var text = System.Text.Encoding.UTF8.GetString(request.downloadHandler.data); observer.OnNext(text); observer.OnCompleted(); } } } static IEnumerator FetchAssetBundle(UnityWebRequest request, IDictionary<string, string> headers, IObserver<AssetBundle> observer, IProgress<float> reportProgress, CancellationToken cancel) { using (request) { yield return Fetch(request, headers, observer, reportProgress, cancel); if (cancel.IsCancellationRequested) { yield break; } if (!string.IsNullOrEmpty(request.error)) { observer.OnError(new UnityWebRequestErrorException(request)); } else { var handler = request.downloadHandler as DownloadHandlerAssetBundle; var assetBundle = (handler != null) ? handler.assetBundle : null; observer.OnNext(assetBundle); observer.OnCompleted(); } } } static IEnumerator FetchBytes(UnityWebRequest request, IDictionary<string, string> headers, IObserver<byte[]> observer, IProgress<float> reportProgress, CancellationToken cancel) { using (request) { yield return Fetch(request, headers, observer, reportProgress, cancel); if (cancel.IsCancellationRequested) { yield break; } if (!string.IsNullOrEmpty(request.error)) { observer.OnError(new UnityWebRequestErrorException(request)); } else { observer.OnNext(request.downloadHandler.data); observer.OnCompleted(); } } } } public class UnityWebRequestErrorException : Exception { public string RawErrorMessage { get; private set; } public bool HasResponse { get; private set; } public string Text { get; private set; } public System.Net.HttpStatusCode StatusCode { get; private set; } public System.Collections.Generic.Dictionary<string, string> ResponseHeaders { get; private set; } public UnityWebRequest Request { get; private set; } // cache the text because if www was disposed, can't access it. public UnityWebRequestErrorException(UnityWebRequest request) { this.Request = request; this.RawErrorMessage = request.error; this.ResponseHeaders = request.GetResponseHeaders(); this.HasResponse = false; StatusCode = (System.Net.HttpStatusCode)request.responseCode; if (request.downloadHandler != null) { Text = request.downloadHandler.text; } if (request.responseCode != 0) { this.HasResponse = true; } } public override string ToString() { var text = this.Text; if (string.IsNullOrEmpty(text)) { return RawErrorMessage; } else { return RawErrorMessage + " " + text; } } } }

使用方法: 1.下面是Josn方式请求示例

接口形式:

Dictionary<string, string> AlarmDic = new Dictionary<string, string>(); AlarmDic["captcha"] = "value"; AlarmDic["password"] = "123456"; AlarmDic["username"] = "admin"; ObservableWebRequest.PostJson("URL",JsonMapper.ToJson(AlarmDic)).Subscribe(OnPostResultCallBack); ///请求成功后的回调 返回数据 privect void OnPostResultCallBack(string result) { Debug.Log(result); }

以上方法支持传输表头传送表头

2.有表头的Get请求

ObservableWebRequest.Get("URL", new Dictionary<string, string> (){ { "key", "value" } }).Subscribe(OnGetResultCallBack); private void OnGetResultCallBack(string result) { Debug.Log(result); }

3.获取byte[] 的Get请求 支持多个请求同时发送

接口形式:

for (int i = 0; i < 100; i++) { ObservableWebRequest.GetAndGetBytes("FileUrl+TempTest2").Subscribe(OnLoadByteArrCallBack); } ///每次请求回来都会调用 异步处理 privte void OnLoadByteArrCallBack(byte[] result) { Texture2D texture = new Texture2D(0, 0); texture.LoadImage(result); }

4.上传二进制文件 由于懒得封装了 直接扩展在外面了

这个可能看着会复杂点 首先看下 接口的规则

private void UploadBytes() { WWWForm form = new WWWForm(); form.AddBinaryData("fileData","byte[] 数据","path"); form.AddField("fileType", "1"); form.AddField("id", id); var request = UnityWebRequest.Post("URL", form); Dictionary<string, string> headers = new Dictionary<string, string>(); headers["key"] ="value"; request.SetRequestHeader(item.Key, item.Value); request.ToObservable().Subscribe(r => { Debug.Log(r); selectPhotoText.text = "上传完成"; }); }

为啥unity自己有unityWebRequst 我们不用 费劲巴拉的整这个 是因为 UniRx的异步操作非常sao气 同时请求多个的时候 可以分别获取想要的结果

而unityWebRequst如果同时请求多个的话,只返回一个 你无法同时拿到返回结果 ,相信在实际开发过程中有些朋友经常会遇到这个问题。

好啦 就先这么多, 有时间在补充!

最新回复(0)