基於.NET 7 的 WebTransport 實現雙向通信

Web Transport 簡介

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 配合使用。

在 .NET 7 中使用 WebTransport

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;

在 JavaScript 中使用 WebTransport

傳入服務地址並創建 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

希望對您有用!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章