Chạy Unity WebGL với ASP.NET Core
Môi trường xác minh
- Windows
-
- cửa sổ 11
- Biên tập viên Unity
-
- 2020.3.25f1
- Visual Studio
-
- Visual Studio 2022
- Lõi ASP.NET
-
- ASP.NET lõi 6.0
- Dịch vụ thông tin Internet (IIS)
-
- IIS 10,0
Lúc đầu
Tìm hiểu cách chạy đầu ra trò chơi dưới dạng WebGL trong Unity trên máy chủ web chạy ASP.NET Core. Đối với các chương trình trò chơi, hãy sử dụng các chương trình đầu ra trong các bước mẹo bên dưới. Ví dụ trò chơi sử dụng Microgame 2D Platformer, có thể được tạo từ Unity Hub.
Tôi sẽ giải thích cách thiết lập "WebGL không nén", "WebGL nén bằng Gzip" và "WebGL nén bằng Brotli" để chạy các trò chơi WebGL. Thủ tục là giống nhau cho tất cả chúng.
Chúng tôi đang sử dụng Visual Studio 2022 ASP.NET Core 6.0, nhưng các phiên bản cũ hơn có thể sẽ hoạt động. Tuy nhiên, cấu trúc của mã ban đầu là khác nhau đối với mỗi phiên bản, vì vậy hãy tự hiểu sự khác biệt.
Tạo một dự án cốt lõi ASP.NET
Khởi chạy "Visual Studio 2022" từ menu bắt đầu.
Chọn Tạo dự án mới.
Lần này, chọn "ASP.NET Core Web App" làm mẫu. Nếu bạn đang chạy trên ASP.NET Core, bạn có thể chạy các mẫu khác, nhưng bạn sẽ cần phải làm theo từng mẫu về cách xây dựng nó.
Đặt tên và vị trí dự án một cách tùy ý.
Để nguyên thông tin bổ sung.
Dự án đã được tạo ra.
Chạy WebGL không nén
Chuẩn bị một chương trình WebGL được tạo mà không nén.
Đảm bảo trò chơi hoạt động nhanh chóng
ASP.NET Thử chạy trò chơi WebGL với ít cài đặt hơn mà không tuân theo nghi thức cốt lõi.
Trong ASP.NET Core, bạn không thể truy cập một số tệp WebGL do Unity phát ra ở trạng thái mặc định. Làm cho điều này có thể truy cập được.
Chương trình.cs
Mở từ dự án của bạn Program.cs
. Áp dụng cho các phiên bản Startup.cs
ASP.NET Core trước đó .
Thêm không gian tên vào đầu mã và thay thế phần sau trong mã app.UseStaticFiles();
:
// ここから追加
using Microsoft.AspNetCore.StaticFiles;
// ここまで追加
var builder = WebApplication.CreateBuilder(args);
// --- 省略 ---
app.UseHttpsRedirection();
//app.UseStaticFiles();
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
app.UseRouting();
// --- 省略 ---
.data
, để khi một tệp được truy cập, .wasm
nó có thể được trả về máy khách với Content-Type
tệp .
Triển khai WebGL
Đặt các thư mục tệp sau từ Unity trong dự án wwwroot
của bạn .
- chỉ số.html
- Xây dựng
- Dữ liệu mẫu
Index.cshtml
index.html
Mở liên kết để bạn có thể truy cập nó.
<!-- 省略 -->
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<!-- 追加 -->
<a href="index.html">index.html</a>
Chạy chương trình và đảm bảo trò chơi hoạt động.
Chạy chương trình WebGL trên trang Razor
Trò chơi trước chạy trên một tệp HTML tĩnh, vì vậy nó chạy ở một nơi không liên quan gì đến ASP.NET Core. Nó không phải là rất mong muốn cho tính đồng nhất của chương trình, vì vậy chúng tôi sẽ di chuyển hành vi của tệp HTML sang Razor Pages.
Nhấp chuột phải vào thư mục Trang từ dự án của bạn để thêm mục mới.
Chọn Razor Page - Empty. Không có tên cụ thể được chỉ định, nhưng nó được thêm vào đây WebGL.cshtml
.
Mã được hiển thị.
index.html
Tham khảo nội dung của file và port đến WebGL.cshtml
.
link
Có một số điểm lạ, chẳng hạn như cách đặt thẻ, nhưng tôi sẽ để nó như vậy vì mục đích giải thích đơn giản.
@page
@model UnityPublishWebglAspNetCore.Pages.WebGLModel
@{
}
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">Platformer</div>
</div>
</div>
@section Scripts {
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
var loadingBar = document.querySelector("#unity-loading-bar");
var progressBarFull = document.querySelector("#unity-progress-bar-full");
var fullscreenButton = document.querySelector("#unity-fullscreen-button");
var warningBanner = document.querySelector("#unity-warning");
// 一時的なメッセージバナー/リボンを数秒間表示するか、
// type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
// type == 'warning'の場合、黄色のハイライト色が使用されます。
// この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
// 視覚的に表示される方法をカスタマイズします。
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
}
var div = document.createElement('div');
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == 'error') div.style = 'background: red; padding: 10px;';
else {
if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
setTimeout(function() {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
var buildUrl = "Build";
var loaderUrl = buildUrl + "/WebGL.loader.js";
var config = {
dataUrl: buildUrl + "/WebGL.data",
frameworkUrl: buildUrl + "/WebGL.framework.js",
codeUrl: buildUrl + "/WebGL.wasm",
streamingAssetsUrl: "StreamingAssets",
companyName: "DefaultCompany",
productName: "Platformer",
productVersion: "2.1.0",
showBanner: unityShowBanner,
};
// デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
// キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
// この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
// 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
// ターゲットサイズを自分でレンダリングします。
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
container.className = "unity-mobile";
// モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
// モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
config.devicePixelRatio = 1;
unityShowBanner('WebGL builds are not supported on mobile devices.');
} else {
canvas.style.width = "960px";
canvas.style.height = "600px";
}
loadingBar.style.display = "block";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
</script>
}
Index.cshtml
WebGL
Thêm liên kết đến .
<!-- 省略 -->
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<!-- 追加 -->
<ul>
<li><a href="index.html">index.html</a></li>
<li><a href="WebGL">WebGL</a></li>
</ul>
Cố gắng chạy chương trình. Bạn có thể thấy rằng đầu trang và chân trang được hiển thị trên trang _Layout.cshtml
WebGL theo .
Thay đổi vị trí của tệp WebGL
Tôi đã đặt tệp WebGL ngay dưới , nhưng phương pháp này sẽ ghi đè lên nó khi bạn đặt hai hoặc nhiều tệp WebGL wwwroot
.
Tôi sẽ giải thích làm thế nào để đặt nó trong các thư mục riêng biệt và di chuyển nó.
Trước hết, tạo một thư mục mới có tên là "webgl" và di chuyển nó đến đó. Hai thư mục Build
cần di chuyển là , TemplateData
.
index.html
Tôi đã chuyển nó sang Razor Pages và có thể xóa nó một cách an toàn.
Vì WebGL.cshtml
chúng tôi đã đào sâu hệ thống phân cấp thư mục, chúng tôi cũng sẽ đào sâu đường dẫn được mô tả trong . Hiệu chỉnh là 3 dòng.
Trước khi chỉnh sửa
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
var buildUrl = "Build";
Sau khi chỉnh sửa
<link rel="shortcut icon" href="webgl/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl/TemplateData/style.css">
var buildUrl = "webgl/Build";
Chạy chương trình để xem nó có hoạt động đúng không.
Chạy WebGL nén bằng Gzip
Phần mở rộng của tệp được nén bởi Gzip là , và nó là .gz
một tệp có thể được xử lý bởi ASP.NET Core,
Unity WebGL Content-Type
và được xử lý khác nhau và yêu cầu chuyển đổi.
Đầu tiên, tạo trang và triển khai tệp WebGL.
Vị trí tệp WebGL
wwwroot
webgl-gzip
Tạo một thư mục trong Gzip và sao chép thư mục , từ tệp Build
TemplateData
WebGL bạn đã tạo bằng Gzip.
Tạo một trang dao cạo
Lần WebGLGzip.cshtml
này tạo tệp bằng quy trình tương tự như khi không nén.
Mã như sau với tham chiếu đến Đầu ra trong index.html
Unity.
Đường dẫn khớp với thư mục bạn đã tạo webgl-gzip
trước đó cho các tệp WebGL.
@page
@model UnityPublishWebglAspNetCore.Pages.WebGLGzipModel
@{
}
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">Platformer</div>
</div>
</div>
@section Scripts {
<link rel="shortcut icon" href="webgl-gzip/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl-gzip/TemplateData/style.css">
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
var loadingBar = document.querySelector("#unity-loading-bar");
var progressBarFull = document.querySelector("#unity-progress-bar-full");
var fullscreenButton = document.querySelector("#unity-fullscreen-button");
var warningBanner = document.querySelector("#unity-warning");
// 一時的なメッセージバナー/リボンを数秒間表示するか、
// type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
// type == 'warning'の場合、黄色のハイライト色が使用されます。
// この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
// 視覚的に表示される方法をカスタマイズします。
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
}
var div = document.createElement('div');
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == 'error') div.style = 'background: red; padding: 10px;';
else {
if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
setTimeout(function() {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
var buildUrl = "webgl-gzip/Build";
var loaderUrl = buildUrl + "/WebGL_Gzip.loader.js";
var config = {
dataUrl: buildUrl + "/WebGL_Gzip.data.gz",
frameworkUrl: buildUrl + "/WebGL_Gzip.framework.js.gz",
codeUrl: buildUrl + "/WebGL_Gzip.wasm.gz",
streamingAssetsUrl: "StreamingAssets",
companyName: "DefaultCompany",
productName: "Platformer",
productVersion: "2.1.0",
showBanner: unityShowBanner,
};
// デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
// キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
// この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
// 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
// ターゲットサイズを自分でレンダリングします。
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
container.className = "unity-mobile";
// モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
// モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
config.devicePixelRatio = 1;
unityShowBanner('WebGL builds are not supported on mobile devices.');
} else {
canvas.style.width = "960px";
canvas.style.height = "600px";
}
loadingBar.style.display = "block";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
</script>
}
Sửa đổi để cho phép điều hướng đến Index.cshtml
trang này.
<!-- 省略 -->
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<!-- 追加 -->
<ul>
<li><a href="index.html">index.html</a></li>
<li><a href="WebGL">WebGL</a></li>
<li><a href="WebGLGzip">WebGLGzip</a></li>
</ul>
Chương trình sửa chữa.cs
app.UseStaticFiles
Sửa đổi phần đang xử lý phương thức như sau.
Trước khi chỉnh sửa
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
});
// ここまで追加
Sau khi chỉnh sửa
// ここから追加
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".data"] = "application/octet-stream";
provider.Mappings[".wasm"] = "application/wasm";
provider.Mappings[".br"] = "application/octet-stream"; // .br ファイルにアクセスできるように追加
provider.Mappings[".js"] = "application/javascript"; // 後の変換の為に追加
app.UseStaticFiles(new StaticFileOptions()
{
ContentTypeProvider = provider,
OnPrepareResponse = context =>
{
var path = context.Context.Request.Path.Value;
var extension = Path.GetExtension(path);
// 「.gz」「.br」ファイルにアクセスした場合は Content-Type と Content-Encoding を設定する
if (extension == ".gz" || extension == ".br")
{
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path) ?? "";
if (provider.TryGetContentType(fileNameWithoutExtension, out string? contentType))
{
context.Context.Response.ContentType = contentType;
context.Context.Response.Headers.Add("Content-Encoding", extension == ".gz" ? "gzip" : "br");
}
}
},
});
// ここまで追加
Trong ASP.NET Core .gz
, file Content-Type
application/x-gzip
trả về với .
Như hiện tại, Unity WebGL trên máy khách không thể xác định nó, vì vậy .gz
tôi viết lại và trả về nó theo Content-Type
phần mở rộng của tệp loại trừ .
Content-Encoding
Tôi cũng đặt nó vì nó gzip
là cần thiết.
Nhân tiện, tôi cũng đặt mã Brotli lại với nhau, vì vậy bạn có thể sử dụng mã này như trong thư từ Brotli của mục tiếp theo.
Brotli cũng .br
đặt viết lại Content-Encoding
br
để phù hợp với Content-Type
phần mở rộng của tệp mà không có tệp .
Tuy nhiên, tệp không thể truy cập được theo mặc định trong ASP.NET Core,.br
vì vậy provider.Mappings
tôi đã thêm nó với .br
.
Sau đó, chạy gỡ lỗi và kiểm tra xem trò chơi có hoạt động chính xác không.
Nếu bạn đã thiết lập đúng cách và trò chơi vẫn không hiển thị, hãy thử xóa bộ nhớ cache của trình duyệt web để xóa cookie.
Chạy WebGL nén với Brotli
Quy trình này gần giống như Gzip, thay thế phần Gzip bằng Brotli. Tuy nhiên, tệp Brotli (.br) không thể truy cập theo mặc định trong ASP.NET Core. Bạn cần cấu hình nó để bạn có thể truy cập nó, nhưng nếu bạn đang sử dụng mã tại thời điểm Gzip, nó được hỗ trợ.
Đầu tiên, tạo trang và triển khai tệp WebGL.
Vị trí tệp WebGL
wwwroot
webgl-brotli
Trong Tạo thư mục, sao chép thư mục , từ tệp WebGL bạn đã Build
TemplateData
tạo bằng Brotli.
Tạo một trang dao cạo
Tạo tệp bằng các WebGLBrotli.cshtml
bước tương tự như đối với Gzip.
Mã như sau với tham chiếu đến Đầu ra trong index.html
Unity.
Đường dẫn khớp với thư mục bạn đã tạo webgl-brotli
trước đó cho các tệp WebGL.
@page
@model UnityPublishWebglAspNetCore.Pages.WebGLBrotliModel
@{
}
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=960 height=600></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">Platformer</div>
</div>
</div>
@section Scripts {
<link rel="shortcut icon" href="webgl-brotli/TemplateData/favicon.ico">
<link rel="stylesheet" href="webgl-brotli/TemplateData/style.css">
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
var loadingBar = document.querySelector("#unity-loading-bar");
var progressBarFull = document.querySelector("#unity-progress-bar-full");
var fullscreenButton = document.querySelector("#unity-fullscreen-button");
var warningBanner = document.querySelector("#unity-warning");
// 一時的なメッセージバナー/リボンを数秒間表示するか、
// type == 'error'の場合はキャンバスの上部に永続的なエラーメッセージを表示します。
// type == 'warning'の場合、黄色のハイライト色が使用されます。
// この関数を変更または削除して、重要ではない警告とエラーメッセージがユーザーに表示されるように
// 視覚的に表示される方法をカスタマイズします。
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
}
var div = document.createElement('div');
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == 'error') div.style = 'background: red; padding: 10px;';
else {
if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
setTimeout(function() {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
var buildUrl = "webgl-brotli/Build";
var loaderUrl = buildUrl + "/WebGL_Brotli.loader.js";
var config = {
dataUrl: buildUrl + "/WebGL_Brotli.data.br",
frameworkUrl: buildUrl + "/WebGL_Brotli.framework.js.br",
codeUrl: buildUrl + "/WebGL_Brotli.wasm.br",
streamingAssetsUrl: "StreamingAssets",
companyName: "DefaultCompany",
productName: "Platformer",
productVersion: "2.1.0",
showBanner: unityShowBanner,
};
// デフォルトでは、Unity は WebGL キャンバスレンダリングのターゲットサイズを
// キャンバス要素の DOM サイズ(window.devicePixelRatio でスケーリング)と一致させます。
// この同期がエンジン内で発生しないようにする場合は、これを false に設定し、
// 代わりにサイズを大きくします。 キャンバスの DOM サイズと WebGL は、
// ターゲットサイズを自分でレンダリングします。
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
container.className = "unity-mobile";
// モバイルデバイスでフィルレートのパフォーマンスを低下させないようにし、
// モバイルブラウザで低 DPI モードをデフォルト/オーバーライドします。
config.devicePixelRatio = 1;
unityShowBanner('WebGL builds are not supported on mobile devices.');
} else {
canvas.style.width = "960px";
canvas.style.height = "600px";
}
loadingBar.style.display = "block";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
</script>
}
Sửa đổi để cho phép điều hướng đến Index.cshtml
trang này.
<!-- 省略 -->
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
<!-- 追加 -->
<ul>
<li><a href="index.html">index.html</a></li>
<li><a href="WebGL">WebGL</a></li>
<li><a href="WebGLGzip">WebGLGzip</a></li>
<li><a href="WebGLBrotli">WebGLBrotli</a></li>
</ul>
Chương trình sửa chữa.cs
Nếu bạn sửa đổi nó khi Gzip được hỗ trợ, bạn có thể sử dụng cùng một mã.
Sau khi sửa nó, chạy gỡ lỗi và kiểm tra xem trò chơi có hoạt động không.
Nếu bạn đã thiết lập đúng cách và trò chơi vẫn không hiển thị, hãy thử xóa bộ nhớ cache của trình duyệt web để xóa cookie.
Hiểu các triệu chứng khi truy cập tệp Brotli trên máy chủ web IIS
Brotli không được IIS hỗ trợ theo mặc định, vì vậy cấu hình ở phía IIS là bắt buộc. Có vẻ như nó có thể được xử lý bằng cách thực hiện các cài đặt nâng cao, nhưng tôi sẽ không giải thích nó trong mẹo này. Vui lòng tham khảo thông tin được liên kết bên dưới.
- asp.net nén brotli lõi 2.2 không hoạt động trên IIS?
- Tổng quan về nén IIS
- WebGL: Mẫu mã cấu hình máy chủ
- WebGL - Triển khai các bản dựng nén
thông báo lỗi
Unable to load file webgl-brotli/Build/WebGL_Brotli.framework.js.br! Check that the file exists on the remote server. (also check browser Console and Devtools Network tab to debug)