WebTransport 是一個新的 Web API,使用 HTTP/3 協定來支援雙向傳輸。它用於 Web 使用者端和 HTTP/3 伺服器之間的雙向通訊。它支援通過 不可靠的 Datagrams API 傳送資料,也支援可靠的 Stream API 傳送資料。
因為 HTTP/3 使用了基於 UDP 的 QUIC 協定,所以 Web Transport 可以在一個連線上建立多個流,而且不會相互阻塞。
WebTransport 支援三種不同型別的流量:資料包(datagrams) 以及單向流和雙向流。
WebTransport 的設計基於現代 Web 平臺基本型別(比如 Streams API)。它在很大程度上依賴於 promise,並且可以很好地與 async 和 await 配合使用。
WebTransport 在 .NET 7 以及以上版本可用,我們新建一個 .NET Core 的空專案,修改 csproj 檔案,設定 EnablePreviewFeatures 和 RuntimeHostConfigurationOption ,如下
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<EnablePreviewFeatures>True</EnablePreviewFeatures>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="Microsoft.AspNetCore.Server.Kestrel.Experimental.WebTransportAndH3Datagrams" Value="true" />
</ItemGroup>
</Project>
要設定 WebTransport 連線,首先需要設定 Web 主機並通過 HTTP/3 偵聽埠:
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, options) =>
{
// Port configured for WebTransport
options.ListenAnyIP([SOME PORT], listenOptions =>
{
listenOptions.UseHttps(GenerateManualCertificate());
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
});
});
var app = builder.Build();
修改下面的程式碼,接收 WebTransport 請求和對談。
app.Run(async (context) =>
{
var feature = context.Features.GetRequiredFeature<IHttpWebTransportFeature>();
if (!feature.IsWebTransportRequest)
{
return;
}
var session = await feature.AcceptAsync(CancellationToken.None);
});
await app.RunAsync();
等待 AcceptStreamAsync 方法直到接收到一個 Stream,使用 stream.Transport.Input 寫入資料,stream.Transport.Output 讀取資料。
var stream = await session.AcceptStreamAsync(CancellationToken.None);
var inputPipe = stream.Transport.Input;
var outputPipe = stream.Transport.Output;
傳入服務地址並建立 WebTransport 範例, transport.ready 完成,此時連線就可以使用了。
const url = 'https://localhost:5002';
const transport = new WebTransport(url);
await transport.ready;
連線到伺服器後,可以使用 Streams API 傳送和接收資料。
// Send two Uint8Arrays to the server.
const stream = await transport.createSendStream();
const writer = stream.writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
try {
await writer.close();
console.log('All data has been sent.');
} catch (error) {
console.error(`An error occurred: ${error}`);
}
下面是一個具體的例子,使用 WebTransport 實現了使用者端和伺服器端的雙向通訊。
完成的程式碼在下面的 github 地址。
https://github.com/danroth27/AspNetCoreNet7Samples/tree/main/WebTransportInteractiveSampleApp
希望對您有用!