WebHop.Gateway
2.0.2
dotnet add package WebHop.Gateway --version 2.0.2
NuGet\Install-Package WebHop.Gateway -Version 2.0.2
<PackageReference Include="WebHop.Gateway" Version="2.0.2" />
<PackageVersion Include="WebHop.Gateway" Version="2.0.2" />
<PackageReference Include="WebHop.Gateway" />
paket add WebHop.Gateway --version 2.0.2
#r "nuget: WebHop.Gateway, 2.0.2"
#:package WebHop.Gateway@2.0.2
#addin nuget:?package=WebHop.Gateway&version=2.0.2
#tool nuget:?package=WebHop.Gateway&version=2.0.2
WebHop.Gateway
The public side of WebHop, as ASP.NET Core middleware. Apps behind NAT or a firewall open WebSocket tunnels to the gateway, and the gateway forwards public HTTP traffic through them with YARP. Request and response bodies stream in both directions; WebSockets, server-sent events and multi-value headers pass through.
browser ──HTTP──▶ WebHop.Gateway ◀──WebSocket tunnels── your app
(public host) (behind NAT, no open ports)
Apps connect with WebHop.Origin, or any local server with the webhop command line tool.
Standalone gateway
dotnet new web -n MyGateway
cd MyGateway
dotnet add package WebHop.Gateway
using WebHop.Gateway;
GatewayApp.Create(args).Run();
GatewayApp is the complete gateway: unlimited request body size, the WebHop middleware, and a 503 while no app is connected.
For a gateway ready to deploy without writing code, with error pages for visitors and the IIS settings Azure App Service needs, publish WebHop.Gateway.Host from the repository.
In an existing app
builder.Services.AddWebHopGateway();
var app = builder.Build();
app.UseWebSockets();
app.UseWebHopGateway();
app.MapGet("/", () => "No app connected"); // your own content
Every request is forwarded to a connected app; with several connected, they take turns. While none is connected, requests fall through to the rest of your pipeline.
Auth token
Only apps that present the gateway's auth token can open tunnels; public visitors don't need it. Set it with the WEBHOP_AUTHTOKEN environment variable or the WebHop:AuthToken configuration key (the setting wins when both are set). Without one the gateway still starts, but rejects every tunnel and logs an error.
The token is sent each time a tunnel opens, so serve the gateway over https outside local development.
Endpoints
| Path | Purpose |
|---|---|
/webhop |
Where apps open their tunnels (WebSocket) |
/webhop/status |
Health check |
| anything else | Forwarded to a connected app |
Forwarded requests carry X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host, plus X-Webhop-Origin-Id and X-Webhop-Request-Id on requests and responses. A request without a response within 120 s gets a 504.
Hosting notes
- Enable WebSockets on the host (on Azure App Service, in the app's configuration).
- Run a single instance: tunnels live in memory, so behind a load balancer a request can land on an instance the app isn't connected to and get a 503.
- Behind a TLS-terminating reverse proxy (nginx, Traefik, Caddy), set
ASPNETCORE_FORWARDEDHEADERS_ENABLED=trueso apps see the client's real IP and scheme. The proxy must also pass WebSocket upgrades on/webhop; nginx needsproxy_http_version 1.1and theUpgrade/Connectionheaders for this.
Azure App Service
- Enable WebSockets in the app's configuration.
- Set
WEBHOP_AUTHTOKENas an application setting. - Point your apps at
https://<your-app>.azurewebsites.net/. - Mind the plan's WebSocket limit per instance: Free allows 5, Shared 35, Basic 350, Standard and up have no fixed limit. Every tunnel is one WebSocket, and so is every WebSocket your visitors open. On Free and Shared the gateway tells apps how many tunnels each may open (60% of the limit), leaving room for visitors;
WebHop:MaxWebSocketsoverrides the detected limit.
More
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- WebHop.Core (>= 2.0.2)
- Yarp.ReverseProxy (>= 2.3.0)
-
net7.0
- WebHop.Core (>= 2.0.2)
- Yarp.ReverseProxy (>= 2.3.0)
-
net8.0
- WebHop.Core (>= 2.0.2)
- Yarp.ReverseProxy (>= 2.3.0)
-
net9.0
- WebHop.Core (>= 2.0.2)
- Yarp.ReverseProxy (>= 2.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.