Пример #1
0
 void addDFile(XmlPatch.DFileInfo df)
 {
     lock (mDFS)
     {
         if (mDFS.ContainsKey(df.id))
         {
             return;
         }
         mDFS[df.id] = df;
     }
 }
Пример #2
0
            void CDNFileDownThread(object param)
            {
                int threadIdx = (int)param;

                //Log.I("cdn sub thread start",Log.Tag.Update);
                XmlPatch.DFileInfo df  = null;
                byte[]             buf = new byte[RecvBuffSize];
                int pLen       = mThis.mDataPath.Length;
                int retryTimes = 0;

                while (!mError)
                {
                    if (retryTimes <= 0)
                    {//取下一个下载文件
                        lock (mLock)
                        {
                            if (mIDS.Count <= 0)
                            {
                                break;
                            }
                            mIndex = ++mIndex % mIDS.Count;
                            df     = mThis.lockDFile(mIDS[mIndex]);
                            if (df == null)
                            {
                                continue;
                            }
                            if (df.size <= 0)
                            {
                                mIDS.RemoveAt(mIndex);
                                continue;
                            }
                        }
                    }

                    HttpWebResponse rt = null;
                    FileStream      fs = null;
                    Stream          st = null;
                    try
                    {
                        string savePath = df.path;
                        string tmpPath  = savePath + "." + mThis.mNewVersion + ".tmp";
                        fs = File.Exists(tmpPath)?new FileStream(tmpPath, FileMode.Append, FileAccess.Write, FileShare.Write):new FileStream(tmpPath, FileMode.Create);
                        int tmpSize = (int)fs.Length;
                        if (tmpSize < df.size)
                        {
                            mHWRS[threadIdx] = HttpWebRequest.Create(new Uri(mThis.mUrl + savePath.Substring(pLen))) as HttpWebRequest;
                            //mHWRS[threadIdx].KeepAlive = true;//保持连接,否则消耗服务器的连接数,有的服务器设置会强制关闭连接/
                            mHWRS[threadIdx].KeepAlive        = false;
                            mHWRS[threadIdx].Timeout          = TimeOut;
                            mHWRS[threadIdx].ReadWriteTimeout = TimeOut;
                            mHWRS[threadIdx].AddRange("bytes", tmpSize);//必须在GetResponse之前设置
                            rt = mHWRS[threadIdx].GetResponse() as HttpWebResponse;
                            st = rt.GetResponseStream();
                            int size = ((int)df.size) - tmpSize;
                            int n    = 0;
                            while (size > 0)
                            {
                                n = st.Read(buf, 0, size > RecvBuffSize?RecvBuffSize:size);
                                if (n <= 0)
                                {
                                    throw new Exception("HttpWebResponse read exception");
                                }
                                fs.Write(buf, 0, n);
                                size -= n;
                                Interlocked.Add(ref mDownSize, n);
                            }
                        }
                        fs.Close();

                        if (File.Exists(savePath))
                        {
                            File.Delete(savePath);
                        }
                        File.Move(tmpPath, savePath);
                        if (df.md5 != FileUtils.GetMd5Hash(savePath))
                        {
                            File.Delete(savePath);
                            Interlocked.Add(ref mDownSize, -df.size);
                            throw new Exception("data md5 error");
                        }
                        retryTimes = 0;
                        df.size    = 0;//标记文件下载完成
                        df.locked  = false;
                    }
                    catch (Exception e)
                    {
                        ++retryTimes;
                        if (mCancel || retryTimes >= 3)
                        {
                            mError    = true;
                            df.locked = false;
                            Log.e("download failed file=" + df.path, Log.Tag.Update);
                            Log.e(e, Log.Tag.Update);
                        }
                        else
                        {
                            Log.i("retry download file=" + df.path, Log.Tag.Update);
                            Thread.Sleep(300);
                        }
                    }
                    finally
                    {
                        if (null != fs)
                        {
                            fs.Close();
                        }
                        if (null != st)
                        {
                            st.Close();
                        }
                        if (null != rt)
                        {
                            rt.Close();
                        }
                    }
                }
                Interlocked.Increment(ref mExitCount);
                //Log.I("cdn sub thread exit", Log.Tag.Update);
            }
Пример #3
0
            void CDNDownThread(object param)
            {
                float  progress = 0;
                Action action   = Action.DownXml;

                try
                {
                    //获取版本配置文件/
                    EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Doing, action));
                    if (mThis.mPatch.getVersion() != mThis.mNewVersion)
                    {
                        mHWR                  = HttpWebRequest.Create(new Uri(mThis.mUrl + "version.xml")) as HttpWebRequest;
                        mHWR.KeepAlive        = false;
                        mHWR.Timeout          = TimeOut;
                        mHWR.ReadWriteTimeout = TimeOut;
                        HttpWebResponse rt = mHWR.GetResponse() as HttpWebResponse;
                        recvXml(mThis.mDataPath + "version.xml", rt.GetResponseStream(), (int)rt.ContentLength);
                        rt.Close();
                        mTotalSize = 0;
                    }
                    mHWR = null;

                    //计算下载文件
                    if (mTotalSize <= 0)
                    {
                        action = Action.CalcSize;
                        mIDS   = new List <int>();
                        mParts = mThis.mPatch.getDepends(mParts);
                        List <XmlPatch.DFileInfo> dfs = mThis.mPatch.listDownFiles(delegate(float percent){ EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress = percent, State.Doing, action)); }, ref mCancel, mParts);
                        long size    = 0;
                        long tmpSize = 0;
                        for (int i = 0, max = dfs.Count; i < max; ++i)
                        {
                            XmlPatch.DFileInfo df = dfs[i];
                            mThis.addDFile(dfs[i]);
                            mIDS.Add(df.id);

                            size += df.size;
                            FileInfo f = new FileInfo(df.path + "." + mThis.mNewVersion + ".tmp");
                            if (f.Exists)
                            {
                                tmpSize += f.Length;
                            }
                        }

                        mTotalSize = size;
                        mDownSize  = tmpSize;
                        System.GC.Collect();
                        if ((Action)param == Action.CalcSize)
                        {
                            EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Idle, action));
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    mHWR   = null;
                    mError = true;
                    Log.e(e, Log.Tag.Update);
                    EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Failed, action));
                    return;
                }


                //开启文件下载线程/
                progress = mTotalSize > 0?1.0f * Interlocked.Read(ref mDownSize) / mTotalSize:1;
                action   = Action.DownFile;
                EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Doing, action));
                List <Thread> lsThread = new List <Thread> ();

                for (int i = 0; i < mHWRS.Length; ++i)
                {
                    Thread t = new Thread(new ParameterizedThreadStart(CDNFileDownThread));
                    lsThread.Add(t);
                    t.Start(i);
                }
                //通知显示资源下载进度/
                while (Interlocked.Read(ref mExitCount) < lsThread.Count)
                {
                    progress = mTotalSize > 0?1.0f * Interlocked.Read(ref mDownSize) / mTotalSize:1;
                    EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Doing, action));
                    Thread.Sleep(100);
                }
                //等待下载线程结束/
                for (int i = 0; i < lsThread.Count; ++i)
                {
                    lsThread[i].Join();
                }

                //解压lua脚本
                mError = !unzipLua(ref action, ref progress);
                //===========
                Log.i("cdn main thread exit,task name=" + this.mName, Log.Tag.Update);
                if (!mError)
                {
                    //通知更新完成
                    EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, 1, State.Completed, action));
                }
                else
                {
                    Thread.Sleep(500);
                    EventMgr.single.PostEvent("UpdateEvent", new UpdateEvent(this, progress, State.Failed, action));
                }
            }