Autodesk Forge API服務的數據中心是基於AWS的海外服務搭建的,於是,因爲衆所周知的緣由,國內部分地區(依ISP而異)訪問Forge雲端口的速度會受到必定程度的影響。特別是Forge Viewer瀏覽大型模型,以及對反饋時間比較銘感且涉及關鍵業務的工做流等諸多場景,對於服務端的存取效率有者較高要求。因此,如何處理好雲端數據的訪問與協同工做流,包括離線加載、雲端緩存等方案的最佳實踐,是你們一直關注的問題。今天,咱們就總結一下幾種常見的實現方式,以期實現流程與性能的優化。css
往期有這兩篇文章可供參考:離線模型的下載和部署和Viewer模型加載本地離線緩存實戰,該文介紹了使用新近瀏覽器原生的Service-Worker和Cache API緩存模型的方案。react
可是在Viewer模型加載本地離線緩存實戰的實例代碼中,針對Viewer庫和線上模型資源自己的緩存是經過靜態路徑實現的:git
//https://github.com/petrbroz/forge-disconnected/blob/master/public/service-worker.js const STATIC_URLS = [ 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/style.css', 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/viewer3D.js', 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/lmvworker.js', 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/res/locales/en/allstrings.json', 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/res/environments/SharpHighlights_irr.logluv.dds', 'https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/res/environments/SharpHighlights_mipdrop.logluv.dds', ...
該實現存在幾點問題:github
所以,在咱們後續的實戰Forge Viewer漸進應用一文中,採用先註冊完成緩存任務的Service Worker再加載Viewer庫的流程。如此一來,Viewer庫依賴與模型資源的加載請求也會自動獲得緩存,無需手動干預緩存過程,大幅增進代碼的可維護性:web
navigator.serviceWorker.register('/service-worker.js').then((registration) => { let script = document.createElement('script'); script.onload = function () { const viewer = new Autodesk.Viewing.Private.GuiViewer3D(myViewerDiv); Autodesk.Viewing.Initializer(options, () => { ... //按需以在線或離線模式初始化Viewer並加載模型 viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => { const channel = new MessageChannel(); channel.port1.onmessage = (event) => console.log(event); navigator.serviceWorker.controller.postMessage({ operation: 'EXECUTE_CACHE' }, [channel.port2]); // 模型加載完成,該模型所需資源已做記錄,遂向ServiceWorker發送消息,開始緩存所需資源 }) }); }; script.src = "https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/viewer3D.min.js"; document.head.appendChild(script) //待Worker註冊完畢開始做動後再載入Viewer,實現Viewer庫及其依賴的自動緩存 })
Autodesk.Viewing.endpoint.setEndpointAndApi
來重定向獲取模型數據的URL:Autodesk.Viewing.Initializer(options, function(){ Autodesk.Viewing.endpoint.setEndpointAndApi('https://yourhostname/your/proxy/service/path') ...
隨後在你的服務端將Viewer發來的請求代理至Forge API雲服務https://developer.api.autodesk.com
便可,注意保留Viewer原生請求的路徑,這裏還能夠根據Forge服務上的模型所在的數據中心按需爲轉發目的地做進一步設置,詳見:BIM 360 Docs API在操做歐洲數據中心內容的一些調整。spring
Autodesk.Viewing.Initializer(options, function(){ Autodesk.Viewing.endpoint.HTTP_REQUEST_HEADERS = {'X-My-Custom-Header':'233', ...} ...
固然,咱們還需在本身的服務端設置預檢請求(Pre-flight)的返回中Access-Control-Allow-Headers
的請求頭,容許以前爲Viewer設置的請求頭不被瀏覽器的跨域安全機制攔截。apache
File
協議的模型加載,須要經過重寫WebView並攔截http請求,返回靜態資源。webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http://my/path/to/svf")) { // 返回靜態模型資源 return true; } } });
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) { if navigationAction.navigationType == .linkActivated { if webView.url!.absoluteString == "http://path/to/my/static/svf" { //返回靜態模型資源 return } } decisionHandler(.allow) }
針對跨平臺的框架,不建議使用搭設本地靜態服務器的方式克服Viewer不支持File
協議的問題,由於不少Android ROM處於安全考量已經屏蔽了該特性。json
onShouldStartLoadWithRequest
攔截並返回靜態模型:onShouldStartLoadWithRequest = (event) => { var url = event.url; if (url && url.length) { if (url.indexOf('http://my/path/to/svf') == 0) { //返回靜態模型資源 } } return true; };
Ionic框架segmentfault
onShouldStartLoadWithRequest
攔截並返回靜態模型cdvfile://path/to/svf
Q:可否避免將模型上傳到Forge數據平臺,直接進行轉換?
Q:能否實現Viewer的徹底本地化?即將Viewer庫和模型渲染資源下載到本地?
Q: 那如何修改Viewer源代碼?我有擴展原生邏輯的需求。
Piggyback
的方式,即在本身的邏輯中動態的替換、擴展Viewer自身的函數Q: 針對離線加載模型的場景,如何有效的提取Viewer可讀的模型文件(SVF)到本地?