コード例 #1
0
        //unity www的设计是:new出来的瞬间,请求就立即发起了
        //由于排队的需求,只能推迟new的时机
        private void BeginRequest(WWWRequest req)
        {
            WWW www = null;

            switch (req.Type)
            {
            case RequestType.Login:
                www = new WWW(req.Url, req.Data);
                break;

            case RequestType.Get:
                www = new WWW(req.Url, null, req.Headers);
                break;

            case RequestType.Post:
                www = new WWW(req.Url, req.Data, req.Headers);
                break;

            default:
                InfoTips.LogWarning("undefined type: " + req.Type.ToString());
                break;
            }

            req.RawWWW    = www;
            req.StartTime = DateTime.Now;

            sendingRequests.Add(requestIdGen++, req);
        }
コード例 #2
0
        public void Post(string resource, string jsonString, OnHttpResponse callback)
        {
            var fullURL = GetHttpPrefix() + resource;
            var headers = GetAuthHeader();

            headers.Add("Content-Type", "application/json");

            var postJson = jsonString;//.ToString();

            InfoTips.LogInfo("[HttpPost] " + fullURL);
            InfoTips.LogInfo("postJson:" + postJson + "--Headers:" + headers);

            var formData = Encoding.UTF8.GetBytes(jsonString);

            var req = new WWWRequest()
            {
                Data         = formData,
                Headers      = headers,
                RespCallback = RespWrapper(callback),
                Type         = RequestType.Post,
                Url          = fullURL
            };

            waitingRequests.Enqueue(req);
        }
コード例 #3
0
        private static byte[] GetMultipartFormData(Dictionary <string, object> postParameters, string boundary)
        {
            Stream formDataStream = new System.IO.MemoryStream();
            bool   needsCLRF      = false;

            foreach (var param in postParameters)
            {
                // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
                // Skip it on the first parameter, add it to subsequent parameters.
                if (needsCLRF)
                {
                    formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));
                }

                needsCLRF = true;

                if (param.Value is FileParameter)
                {
                    FileParameter fileToUpload = (FileParameter)param.Value;

                    // Add just the first part of this param, since we will write the file data directly to the Stream
                    string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n",
                                                  boundary,
                                                  param.Key,
                                                  fileToUpload.FileName ?? param.Key,
                                                  fileToUpload.ContentType ?? "application/octet-stream");

                    //UnityEngine.InfoTips.LogInfo(header);

                    formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header));

                    // Write the file data directly to the Stream, rather than serializing it to a string.
                    formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
                }
                else
                {
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
                                                    boundary,
                                                    param.Key,
                                                    param.Value);
                    formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
                }
            }

            // Add the end of the request.  Start with a newline
            string footer = "\r\n--" + boundary + "--\r\n";

            formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

            // Dump the Stream into a byte[]
            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            InfoTips.LogInfo(Encoding.UTF8.GetString(formData) + "");

            return(formData);
        }
コード例 #4
0
        private void LoadNext()
        {
            var mat     = toLoadMats[0];
            var matCopy = mat;

            InfoTips.LogInfo("材质AB包URL:" + mat.url);
            HttpGetAb(mat.url, ab =>
            {
                StartCoroutine(LoadProceduralMaterial(ab, matCopy, null));
            });
        }
コード例 #5
0
 /// <summary>
 /// cache item
 /// </summary>
 /// <param name="matName"></param>
 /// <returns></returns>
 public MatCacheItem GetByName(string matName)
 {
     if (items.ContainsKey(matName))
     {
         return(items[matName]);
     }
     else
     {
         InfoTips.LogWarning("找不到该材质:" + matName);
         return(null);
     }
 }
コード例 #6
0
 /// <summary>
 /// info
 /// </summary>
 /// <param name="tagName"></param>
 /// <returns></returns>
 public List <MatCacheItem> GetByTag(string tagName)
 {
     if (itemsByTag.ContainsKey(tagName))
     {
         return(itemsByTag[tagName]);
     }
     else
     {
         InfoTips.LogWarning("找不到该材质:" + tagName);
         return(null);
     }
 }
コード例 #7
0
        public void RemoveCache()
        {
            var allCacheFiles = Directory.GetFiles(CacheFolder);
            var count         = 0;

            foreach (var file in allCacheFiles)
            {
                File.Delete(file);
                count++;
            }

            InfoTips.LogInfo("[Http] Remove total:" + count.ToString() + " cache files");
        }
コード例 #8
0
        /// <summary>
        /// load单个材质,保证每个回调都必然被调用
        /// </summary>
        public void LoadMat(string matName, Action <MatCacheItem> callback)
        {
            if (items.ContainsKey(matName))
            {
                callback(items[matName]);
                return;
            }

            //幸好不是真正的多线程
            if (loadCallbacksCache.ContainsKey(matName))
            {
                loadCallbacksCache[matName].Add(callback);
                return;
            }

            var found = false;

            foreach (var item in AllMatInfo)
            {
                if (item.name == matName)
                {
                    found = true;

                    HttpGetAb(item.url, ab =>
                    {
                        StartCoroutine(LoadProceduralMaterial(ab, item, cacheItem =>
                        {
                            var callbackList = loadCallbacksCache[matName];
                            foreach (var cb in callbackList)
                            {
                                cb(cacheItem);
                            }
                        }));
                    });

                    loadCallbacksCache.Add(matName, new List <Action <MatCacheItem> >()
                    {
                        callback
                    });

                    break;
                }
            }

            if (!found)
            {
                InfoTips.LogWarning(matName + "not found");
                callback(null);
            }
        }
コード例 #9
0
        //需要解json
        private HttpResp GenerateResp(WWW www)
        {
            if (www == null)
            {
                return(GenTimeoutResp());
            }

            var resp = new HttpResp();

            if (!string.IsNullOrEmpty(www.error))
            {
                resp.Error     = HttpResp.ErrorType.NetworkError;
                resp.ErrorText = www.error;
            }
            else
            {
                try
                {
                    var respJson = JsonUtility.FromJson <JsonBase>(www.text);

                    if (respJson.error == EXPIRED_ERROR)
                    {
                        resp.Error     = HttpResp.ErrorType.AccessExpired;
                        resp.ErrorText = resp.Error.ToString();
                    }
                    else if (!string.IsNullOrEmpty(respJson.error))
                    {
                        resp.Error     = HttpResp.ErrorType.LogicError;
                        resp.ErrorText = respJson.error;
                    }
                    else
                    {
                        resp.Error = HttpResp.ErrorType.None;
                    }
                }
                catch (Exception e)
                {
                    InfoTips.LogWarning("parse json error: " + e.ToString());

                    resp.Error     = HttpResp.ErrorType.JsonError;
                    resp.ErrorText = e.ToString();
                }
            }

            resp.WwwText = www.text;
            return(resp);
        }
コード例 #10
0
        /// <summary>
        /// 普通get
        /// </summary>
        public void Get(string resource, NameValueCollection query, OnHttpResponse callback)
        {
            var fullURL = GetHttpPrefix() + resource + QueryToString(query);

            InfoTips.LogInfo("[HttpGet] " + fullURL);

            var req = new WWWRequest()
            {
                Data         = null,
                Headers      = GetAuthHeader(),
                RespCallback = RespWrapper(callback),
                Type         = RequestType.Get,
                Url          = fullURL
            };

            waitingRequests.Enqueue(req);
        }
コード例 #11
0
        private void GetRaw(string resource, NameValueCollection query, Action <WWW> callback)
        {
            var fullURL = resource + QueryToString(query);

            InfoTips.LogInfo("[HttpPrivateGet] " + fullURL);

            var req = new WWWRequest()
            {
                Data         = null,
                Headers      = GetAuthHeader(),
                RespCallback = callback,
                Type         = RequestType.Get,
                Url          = fullURL
            };

            waitingRequests.Enqueue(req);
        }
コード例 #12
0
        private void HttpGetAb(string url, Action <AssetBundle> callback)
        {
            WWWManager.Instance.GetFile(url, LocalCacheEntry.CacheType.AssetBundle, (resp, entry) =>
            {
                if (resp.Error != HttpResp.ErrorType.None)
                {
                    if (OnLoadError != null)
                    {
                        OnLoadError(url);
                    }

                    InfoTips.LogWarning("Get Material AssetBundle Error: " + resp.ToString());
                }
                else
                {
                    callback(entry.AB);
                }
            });
        }
コード例 #13
0
        private void HttpGetAllMats(Action <List <MaterialInfo> > callback, string tags = "")
        {
            WWWManager.Instance.Get("meterials/search", new NameValueCollection()
            {
                { "tags", tags }
            }, resp =>
            {
                if (resp.Error != HttpResp.ErrorType.None)
                {
                    if (OnLoadError != null)
                    {
                        OnLoadError("");
                    }

                    InfoTips.LogWarning("Get Material Error: " + resp.ToString());
                }
                else
                {
                    var mats = JsonUtility.FromJson <MaterialInfoCollection>(resp.WwwText);
                    callback(mats.data);
                }
            });
        }
コード例 #14
0
        /// <summary>
        /// 带本地缓存的http文件获取
        /// 本地版本实际上是同步,网络版本是异步</summary>
        /// <param name="url"></param>
        /// <param name="type"></param>
        /// <param name="callback"></param>
        /// <param name="fromQY">是否是从青云服务器上下载,区别于:百度API获取街景</param>
        public void GetFile(string url, LocalCacheEntry.CacheType type, OnHttpGetFileResponse callback, bool fromQY = true)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("Attempt to getfile from an empty URL");
            }

            // 文件缓存之后的文件名
            var local = URLToLocalPath(url);

            InfoTips.LogInfo("[GetFile] related local path:" + local);

            // 缓存中已经存在
            if (File.Exists(local))
            {
                InfoTips.LogInfo("[GetFile] load from local");

                var fakeResp = new HttpResp();
                fakeResp.Error   = HttpResp.ErrorType.None;
                fakeResp.WwwText = "";

                switch (type)
                {
                case LocalCacheEntry.CacheType.Texture:
                    var tex      = new Texture2D(2, 2);
                    var imgBytes = File.ReadAllBytes(local);
                    tex.LoadImage(imgBytes);

                    callback(fakeResp, new LocalCacheEntry()
                    {
                        Type    = LocalCacheEntry.CacheType.Texture,
                        Texture = tex
                    });
                    break;

                case LocalCacheEntry.CacheType.Fbx:
                    callback(fakeResp, new LocalCacheEntry()
                    {
                        Type    = LocalCacheEntry.CacheType.Fbx,
                        FbxPath = local
                    });
                    break;

                case LocalCacheEntry.CacheType.AssetBundle:
                    var ab = AssetBundle.LoadFromFile(local);

                    callback(fakeResp, new LocalCacheEntry()
                    {
                        Type = LocalCacheEntry.CacheType.AssetBundle,
                        AB   = ab
                    });
                    break;

                case LocalCacheEntry.CacheType.Raw:
                    var bytes = File.ReadAllBytes(local);

                    callback(fakeResp, new LocalCacheEntry()
                    {
                        Type  = LocalCacheEntry.CacheType.Raw,
                        Bytes = bytes
                    });

                    break;

                default:
                    break;
                }
            }
            else
            {
                InfoTips.LogInfo("[GetFile] load from remote");

                string realUrl;
                NameValueCollection query;

                if (fromQY)
                {
                    realUrl = GetHttpPrefix() + "entities/download";
                    query   = new NameValueCollection()
                    {
                        { "path", url }
                    };
                }
                else
                {
                    realUrl = url;
                    query   = null;
                }

                GetRaw(realUrl, query, www =>
                {
                    var resp = GenerateGetfileResp(www);

                    if (resp.Error != HttpResp.ErrorType.None)
                    {
                        callback(resp, null);
                    }
                    else
                    {
                        //write cache
                        //TODO: more scientific way: async
                        var localPath = URLToLocalPath(url);

                        if (localPath.Length > 250)
                        {
                            throw new IOException("localpath length overflowwww!!!");
                        }

                        File.WriteAllBytes(localPath, www.bytes);

                        switch (type)
                        {
                        case LocalCacheEntry.CacheType.Texture:
                            callback(resp, new LocalCacheEntry()
                            {
                                Type    = LocalCacheEntry.CacheType.Texture,
                                Texture = www.texture
                            });
                            break;

                        case LocalCacheEntry.CacheType.Fbx:
                            callback(resp, new LocalCacheEntry()
                            {
                                Type    = LocalCacheEntry.CacheType.Fbx,
                                FbxPath = localPath
                            });
                            break;

                        case LocalCacheEntry.CacheType.AssetBundle:
                            callback(resp, new LocalCacheEntry()
                            {
                                Type = LocalCacheEntry.CacheType.AssetBundle,
                                AB   = www.assetBundle
                            });
                            break;

                        case LocalCacheEntry.CacheType.Raw:
                            callback(resp, new LocalCacheEntry()
                            {
                                Type  = LocalCacheEntry.CacheType.Raw,
                                Bytes = www.bytes
                            });
                            break;

                        default:
                            break;
                        }
                    }
                });
            }
        }
コード例 #15
0
        private IEnumerator LoadProceduralMaterial(AssetBundle ab, MaterialInfo matInfo, Action <MatCacheItem> loadDone)
        {
            if (ab == null)
            {
                yield break;
            }

            var pm = ab.LoadAllAssets <ProceduralMaterial>()[0];

            if (!pm.isProcessing && autoRebuild)
            {
                pm.RebuildTextures();
            }

            while (pm.isProcessing)
            {
                yield return(new WaitForEndOfFrame());
            }

            InfoTips.LogInfo(pm.name + " material build done");

            // previewer.gameObject.SetActive(true);

            var item = new MatCacheItem();

            item.MatName  = matInfo.name;
            item.Info     = matInfo;
            item.Material = pm;
            item.Loaded   = true;

            items.Add(item.MatName, item);

            //cache mat items by tag
            foreach (var tag in matInfo.Tags)
            {
                if (itemsByTag.ContainsKey(tag))
                {
                    itemsByTag[tag].Add(item);
                }
                else
                {
                    itemsByTag.Add(tag, new List <MatCacheItem>()
                    {
                        item
                    });
                }
            }

            // previewer.gameObject.SetActive(false);

            //可能单个加载
            if (toLoadMats.Contains(matInfo))
            {
                toLoadMats.Remove(matInfo);
            }

            if (loadDone != null)
            {
                loadDone(item);
            }

            if (toLoadMats.Count > 0)
            {
                LoadNext();
            }
            else
            {
                // Debug.Log("load done ----------------------------------------------------------");
            }
        }
コード例 #16
0
        /// <summary>
        /// 网络请求发动机
        /// </summary>
        /// <returns></returns>
        private IEnumerator MainLoop()
        {
            while (true)
            {
                yield return(new WaitForEndOfFrame());

                var now = DateTime.Now;

                //handle response
                if (sendingRequests.Count > 0)
                {
                    // 已经发起过的RawWWW
                    var disposableKeys = new List <int>();

                    foreach (var key in sendingRequests.Keys)
                    {
                        var sendingOne = sendingRequests[key];
                        var www        = sendingOne.RawWWW;

                        var isTimeout = false;

                        if (!www.isDone)
                        {
                            var cost = (now - sendingOne.StartTime).TotalMilliseconds;
                            //timeout
                            if (cost > TimeOut * 1000)
                            {
                                sendingOne.RespCallback(null);
                                isTimeout = true;
                                InfoTips.LogInfo("Timeout cost: " + cost.ToString());
                            }
                            else
                            {
                                // www没有下载完,也没超时,那就继续
                                continue;
                            }
                        }

                        // www,没有完成,但是超时
                        if (!isTimeout)
                        {
                            if (www.error != null)
                            {
                                InfoTips.LogInfo(www.error);
                                sendingOne.RespCallback(www);
                            }
                            else //not timeout & isdone
                            {
                                InfoTips.LogInfo("[HttpResp] " + www.text);
                                sendingOne.RespCallback(www);
                            }
                        }

                        // 既然能走到这里,说明www已经完成
                        www.Dispose();
                        disposableKeys.Add(key);
                    }

                    foreach (var key in disposableKeys)
                    {
                        sendingRequests.Remove(key);
                    }
                }

                //do send
                var availableCount = concurrentLimit - sendingRequests.Count;

                // 当前发起请求数,没有超过阈值,从等待队列中选
                if (availableCount > 0 && waitingRequests.Count > 0)
                {
                    //one packet per frame
                    var req = waitingRequests.Dequeue();

                    BeginRequest(req);
                }
            }
        }
コード例 #17
0
 void Awake()
 {
     IsOnlySaveOnePage = IsEnable = true;
     IsVisible         = true;
     onlyOne           = this;
 }