Learn Forge 系列:Forge 雲端自動化設計服務 - 網絡app部分

上一篇文章中,咱們講解了Forge Design Automation的基本原理和樣例代碼的插件部分。本文繼續前篇,當插件包準備就緒後,轉向forgesample,基本框架流程是:html

1 . app的Configure首先檢測本地可用的bundle壓縮包,即上篇文章編譯好的結果。選擇壓縮包,並選擇雲端Forge執行的引擎。顯然,Revit插件的要Revit引擎。注意選擇合適的版本前端

圖片描述

2 . 點擊【Create/Update】,app將從本地上傳bundle壓縮包到服務端,再經過Forge的雲端自動化服務端口建立自動化App,提交插件包,建立Activity。全部這些準備好後,您的Forge帳戶中就含有了對應的Activity,而Activity鏈接到自動化App,知道使用哪一個插件執行接下來的任務。git

/// <summary>
        /// 建立雲端自動化app,上載插件bundle
        /// </summary>
        [HttpPost]
        [Route("api/forge/designautomation/appbundles")]
        public async Task<IActionResult> CreateAppBundle([FromBody]JObject appBundleSpecs)
        {
        //......
/// <summary>
        /// 建立 activity
        /// </summary>
        [HttpPost]
        [Route("api/forge/designautomation/activities")]
        public async Task<IActionResult> CreateActivity([FromBody]JObject activitySpecs)
        {
         //......

3 . 退出Configure窗口,程序會經過雲端自動化服務獲取Activity列表。在【Existing activities】選擇到須要的Activitygithub

/// <summary>
        /// 獲取該Forge帳戶下全部可用Activity列表
        /// </summary>
        [HttpGet]
        [Route("api/forge/designautomation/activities")]
        public async Task<List<string>> GetDefinedActivities()
        {
             Page<string> activities = await _designAutomation.GetActivitiesAsync();
            //......

4 . 【Input File】選擇到本地的Revit文件,可以使用本例samples文件夾下提供的樣例文件。 json

5 . 輸入須要改變的長和寬,點擊[Start Workitem]. 將執行StartWorkitemsegmentfault

[HttpPost]
        [Route("api/forge/designautomation/workitems")]
        public async Task<IActionResult> StartWorkitem([FromForm]StartWorkitemInput input)
        {
**StartWorkitem**首先把本地Revit上傳到後端,並經過Forge的Data Management API將文件傳到某個bucket,和咱們一般爲了測試Forge Viewer上傳文件到bucket同樣。由於Forge的雲端自動化服務的輸入文件只能從雲存儲而來,因此此案例利用Forge的bucket存儲。您也能夠改造爲從其它數據存儲。

``後端

//....
        // 確保bucket存在,不然建立之
        try
        {
            PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey, null, PostBucketsPayload.PolicyKeyEnum.Transient);
            await buckets.CreateBucketAsync(bucketPayload, "US");
        }
        catch { }; 
         
         //.......
        //上載文件到bucket
        using (StreamReader streamReader = new StreamReader(fileSavePath))
            await objects.UploadObjectAsync(bucketKey, inputFileNameOSS, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream");
        System.IO.File.Delete(fileSavePath);
當這些準備好之後,配置雲端自動化WorkItem的參數:

   1) 輸入參數:一個是原始Revit文件,經過配置access token來拿到
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
                {
                    Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, inputFileNameOSS),
                    Headers = new Dictionary<string, string>()
                     {
                         { "Authorization", "Bearer " + oauth.access_token }
                     }
                };
    ```

2) 須要更改的幾何數據(長寬),經過配置一個json文件。長寬從客戶端提交的輸入而來。api

dynamic inputJson = new JObject();
            inputJson.Width = widthParam;
            inputJson.Height = heigthParam;
            XrefTreeArgument inputJsonArgument = new XrefTreeArgument()
            {
                Url = "data:application/json, " + ((JObject)inputJson).ToString(Formatting.None).Replace("\"", "'")
            };
3) 再配置更新後的Revit文件放置的位置,一樣,本例將把結果文件放回到bucket中。一樣,須要access token。


```
        string outputFileNameOSS = string.Format("{0}_output_{1}", 
                                        DateTime.Now.ToString("yyyyMMddhhmmss"), 
                                        Path.GetFileName(input.inputFile.FileName));  
                    XrefTreeArgument outputFileArgument = new XrefTreeArgument()
                    {
                        Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}",     
                                            bucketKey, outputFileNameOSS),
                        Verb = Verb.Put,
                        Headers = new Dictionary<string, string>()
                           {
                               {"Authorization", "Bearer " + oauth.access_token }
                           }
                    };
```

4) 最後就是提交任務WorkItem,傳入前面配置好的參數,開啓雲端自動化的過程。
string callbackUrl = string.Format("{0}/api/forge/callback/designautomation?id={1}&outputFileName={2}", 
                             OAuthController.GetAppSetting("FORGE_WEBHOOK_URL"), browerConnectionId, 
                             outputFileNameOSS);
            WorkItem workItemSpec = new WorkItem()
            {
                ActivityId = activityName,
                Arguments = new Dictionary<string, IArgument>()
                {
                    { "inputFile", inputFileArgument },
                    { "inputJson",  inputJsonArgument },
                    { "outputFile", outputFileArgument },
                    //回調函數
                    { "onComplete", new XrefTreeArgument { Verb = Verb.Post, Url = callbackUrl } }
                }
            };
            WorkItemStatus workItemStatus = await _designAutomation.CreateWorkItemsAsync(workItemSpec);

雲端自動化開啓後,須要一個過程才結束,能夠經過主動查詢來獲取狀態,而本例採起回調函數的方式,即onComplete。當WorkItem結束後,不管什麼狀況,都自動通知callbackUrl, 帶上WorkItem執行的日誌(log)文件內容。而callbackUrl定義以下:瀏覽器

[HttpPost]
        [Route("/api/forge/callback/designautomation")]
        public async Task<IActionResult> OnCallback(string id, string outputFileName, [FromBody]dynamic body)
        {

因爲默認是本地測試(localhost),回調函數要獲得響應,採起了ngrok作重定向。網絡

但這只是通知了網絡應用的後端,但怎麼自動通知前端瀏覽器呢?本例採用了SignalR. SignalR 是一個ASP .NET 下的類庫,能夠在ASP .NET 的Web項目中實現實時通訊。此部份內容略過,請查閱本例的先後端相關代碼。

當WorkItem成功執行,結果文件導出到Forge的bucket,還會提供一個簽名下載url,出如今客戶端面板,用戶就能把更改後的文件下載來查看了。

圖片描述

運行forgesample,按照Readme要求填寫Forge的client id,client secret,本網絡應用的host,以及用於獲取Design Automation回調結果狀態的ngrok 重定向連接。本文就再也不贅述了。

本例能夠做爲研究其它方案的模板框架,只須要對前端用戶界面作必定修改,提供核心插件模塊,易於調試和診斷Forge雲端自動化全過程。

相關文章
相關標籤/搜索