PeakSWC.RemoteWebViewService.Lib
10.0.15
dotnet add package PeakSWC.RemoteWebViewService.Lib --version 10.0.15
NuGet\Install-Package PeakSWC.RemoteWebViewService.Lib -Version 10.0.15
<PackageReference Include="PeakSWC.RemoteWebViewService.Lib" Version="10.0.15" />
<PackageVersion Include="PeakSWC.RemoteWebViewService.Lib" Version="10.0.15" />
<PackageReference Include="PeakSWC.RemoteWebViewService.Lib" />
paket add PeakSWC.RemoteWebViewService.Lib --version 10.0.15
#r "nuget: PeakSWC.RemoteWebViewService.Lib, 10.0.15"
#:package PeakSWC.RemoteWebViewService.Lib@10.0.15
#addin nuget:?package=PeakSWC.RemoteWebViewService.Lib&version=10.0.15
#tool nuget:?package=PeakSWC.RemoteWebViewService.Lib&version=10.0.15
PeakSWC.RemoteWebViewService.Lib
The RemoteWebViewService as a library. The same code that runs as RemoteWebViewService.exe (and in the
Railway container) can be hosted inside your own process, for example a WPF or WinForms app that shows its
RemoteBlazorWebView UI in a local browser or a WebView2 iframe without a separate server process.
Embedded (in-process)
using PeakSWC.RemoteWebView;
// Loopback, plain HTTP, free ports. Returns once Kestrel is listening; does not block.
await using var server = await RemoteWebViewServer.StartAsync(new RemoteWebViewServerOptions
{
MaxClients = 1,
FrameAncestors = ["'self'", "https://host.example"], // optional
ConfigureLogging = lb => lb.AddDebug(), // optional; default is silent
});
blazorWebView.ServerUri = server.BaseUri; // browsers: http://127.0.0.1:<port>/
blazorWebView.GrpcBaseUri = server.GrpcUri; // native gRPC client: http://127.0.0.1:<grpcPort>/
// The page for a client is new Uri(server.BaseUri, $"app/{blazorWebView.Id}")
await server.StopAsync(); // or dispose
Port = 0(the default) binds a free port; read the real one fromserver.Port/server.BaseUri.- Plain HTTP is allowed only on a loopback address, so no development certificate is needed. Without TLS
there is no ALPN, so browsers (HTTP/1.1, gRPC-Web) and the native gRPC client (HTTP/2) get separate ports.
Set
UseHttps = true(dev certificate) orCertificateto serve both on one HTTPS port. - The embedded host does not change the current directory or thread pool, does not read the host app's
appsettings.jsonor environment variables, and does not hook Ctrl+C or process exit. MaxClientslimits concurrent RemoteWebView clients (a newCreateWebViewgets 503 /Unavailable); browser requests for connected clients are never blocked. WithMaxClients = 1the client-list and file-watcher services are not mapped. The agent hub (doc/Agents.md) is never mapped when embedded.FrameAncestorsaddsContent-Security-Policy: frame-ancestors ...to HTML responses and rejects cross-origin script calls whoseOriginis not listed. Same-origin calls are always allowed.
Experimental: agent registry
The agent registry (AgentHub / AgentAdmin, see doc/Agents.md in the repository) is experimental and may change or be
removed in any release. Its public types are marked [Experimental("RWV001")], so using them produces compiler diagnostic
RWV001; add <NoWarn>$(NoWarn);RWV001</NoWarn> to opt in. The rest of this package is not affected.
Standalone
RemoteWebViewServer.Run(args); // what RemoteWebViewService.exe does
RemoteWebViewServer.Run(5001, maxNumClients: 1, frameAncestors: ["'self'"]); // blocking, HTTPS on loopback
Two-way voice for WPF sessions
Set BlazorWebView.EnableVoice = true before setting HostPage. Use HTTPS for the browser and host connections, and deploy a relay built with voice support. Open the controller through /app/{id} to get its one-time voice grant. In deployments without sign-in, treat the controller link as a credential. Mirror pages have no voice controls or grant.
The controller can request a call. The person at the PC accepts or declines in a separate local WebView2 window. Both sides can mute or hang up, and closing either endpoint ends the call. Voice uses the default input and output devices. The relay forwards call setup messages and WebRTC carries audio directly or through TURN.
Configure Voice__StunUrl for STUN and Voice__TurnUrl with Voice__TurnSecret for a TURN server that supports shared-secret credentials. For example, use turns:turn.example.com:443?transport=tcp for a TURN TLS listener on port 443. Keep the TURN secret on the relay. Configure the HTTPS proxy to forward WebSocket upgrades and preserve the public Host header on /voice/{id}/signal.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- Google.Protobuf (>= 3.36.2)
- Grpc.AspNetCore.Server (>= 2.85.0)
- Grpc.AspNetCore.Web (>= 2.85.0)
- Microsoft.AspNetCore.Components.WebAssembly.Server (>= 10.0.15)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Based on maui 10.0.15
Changes since 10.0.14
Release workflow publishes to NuGet when dry_run is off (trusted publishing, nuget-org approval)
10-client test waits 2 minutes before attaching browsers again (idle sessions must survive)
Server stats tests: the app's own blazor.modules.json is served now (2 bytes fewer per client)
ParticipantsChanged needs relay 10.0.15
Merge PR #85 (module, JS, relay, lifecycle, generator and system test fixes)
README and release notes: sign-in providers, owner key, ParticipantsChanged
Authorization is injected, not compiled in: None, Fake (tests) and AzureB2C providers
Tests: owner URL carries the key; spoofed-owner test waits for the roster
WinForms: OwnerKey is not a designer property
WIP: owner key, names in the roster, ParticipantsChanged, session group check
Remove UTF-8 BOM from embedded blazor.modules.json and clear CS8602 warnings
Use bundled protoc 3.x binary in scripts/protoc.js on Linux CI
Fix bugs across module, JS, relay, lifecycle, generator, and system tests
Browser swarm keeps 300 separate clients, spread over 10 Chromium processes
Fix RunTests.ps1 packaging/tool issues, concurrent browser tests, and MSB3277 warnings
RunTests: -NoBuild runs the tests on what the last run built
Lost-connection test cuts the viewer's connections itself
A lost connection is shown and a /mirror page comes back; unattended hand-over retried; frames follow the latest control change
Web.JS test file as EditWebView writes it
EditWebView keeps this repository's own changes across a run
Upstream source from MAUI 10.0.130 and aspnetcore 10.0.15 (EditWebView run)
Document EditWebView in the release process.
EditWebView: ask for tag dates only on the wanted major version, and print progress
EditWebView prints what a run changed; Web.JS/src and test no longer git-ignored
update packages
EditWebView: fall back to the GitHub CLI sign-in when GITHUB_PAT is not set
Microsoft 10.0 libraries to 10.0.15, SDK 10.0.404; EditWebView re-applies the Web.JS patches
Control test: a browser that has not been told yet is 'not agreed', not an error
Restart test: wait for the restart to start before waiting for the page to return
RunTests: -Filter for a partial browser run; restart test keeps the bar in view
Agent: hand the requester the session's join link
Generator: voice, run-time choices, app-supplied startup values, and a restart that survives a stuck window
Library: a restart request still restarts an app whose UI thread is stuck
Session bar: opt-in Restart button
Shared control: one change of controller at a time
Voice: a mirror page gets the remote end whenever nobody holds it
Relay: every write to the app's stream goes through one guarded method
Shared control: a message from before a hand-off can no longer replace a real one
RunTests: quote the -p: switch so PowerShell passes it whole
RunTests: run every test project, quick suites first
BugBountyTests: the mirror-scroll test ignores the control notices browsers are now sent
ControlTransferTests: the fake browser stream accepts the relay's token overload
Tests for sharing control: relay policy, render acks, URL loading, and end-to-end browser tests
Agent protocol: 'requester' instead of 'technician'; consent fallback is 'Someone'
Unattended address is control=remote; neutral wording in comments, package notes and the voice prompt
Session bar: connection dot, neutral wording, host/remote names on the placeholder
Package release notes for 10.0.15
10.0.15: generator ShareControl/Unattended, compatibility fixes, docs
Build warnings: WebView2 WPF reference, AOT-safe relay JSON/config, RS1032
Unattended sessions: ?control=technician gives the technician control on joining
Remote component frames follow control; roster in join order; document roles
Remote component frames: role follows the page kind, not who has control
Full list: https://github.com/budcribar/RemoteBlazorWebView/compare/10.0.14...eedda77cab529ca84113b6b515e9c62b6969e76d