Skip to content

Repository files navigation

TXTextControl.Web.Collaboration Test App

This ASP.NET Core application is a runnable integration sample for TXTextControl.Web.Collaboration. It demonstrates how an application can maintain a source-document library, create or reopen collaboration rooms, connect the TX Text Control Document Editor through the collaboration Tag Helper, and publish the current room document back to its source.

The sample deliberately keeps application storage separate from collaboration room storage. Files in Data are source documents. A room owns an authoritative TX document that is synchronized automatically while users edit it. The source file changes only when Save to source is selected on the document-library page.

Features

  • Lists .tx and .docx files from the application's Data directory.
  • Creates at most one active room for each source document.
  • Converts DOCX files to TX Text Control Internal Unicode Format before creating a room.
  • Reopens an existing room instead of creating a second room for the same document.
  • Uses protected room-access tokens for owners and invited collaborators.
  • Renders the collaboration presence and sharing interface with the <tx-collaboration> Tag Helper.
  • Uses server-side editor access and TX fragment synchronization for ordinary edits.
  • Persists active collaboration rooms and restores them after an application restart.
  • Exports the authoritative TX master and converts it back to DOCX when required.
  • Detects when a source file was changed outside the room before overwriting it.

Prerequisites

  • .NET 10 SDK
  • A valid TX Text Control license
  • Access to the TX Text Control NuGet packages used by the project

The project references:

  • TXTextControl.TextControl.Core.SDK 34.0.4
  • TXTextControl.Web 34.4.0
  • TXTextControl.Web.DocumentEditor.Backend 34.4.0
  • TXTextControl.Web.Collaboration 34.0.0-alpha, through a project reference by default

Run the sample

From the solution directory:

dotnet run --project tests/TXTextControl.Web.Collaboration.TestApp

The launch profile uses:

  • https://localhost:61484
  • http://localhost:61485

If HTTPS is not trusted locally, use the HTTP address or trust the ASP.NET Core development certificate.

The application starts the TX Text Control Document Editor backend in-process by default. Set TextControl:StartEditorBackend to false when the editor is connected to an externally managed backend.

Try the workflow

  1. Enter the name that should appear in collaboration presence.
  2. Select Add to collaboration for an available source document.
  3. Use Share in the collaboration bar to create an invitation for another user.
  4. Open the invitation in another browser or private window and edit from both sessions.
  5. Return to Document library. The active room continues to contain the current authoritative document.
  6. Select Save to source to export the room master to the original TX or DOCX file.
  7. Select Close room when collaboration is complete.

Closing a room does not implicitly publish it to the source file. Save first when the room's final state should replace the source document.

Document handling

The collaboration package operates exclusively on TX Text Control Internal Unicode Format. Format conversion is therefore an application responsibility:

  • TX sources are passed to CreateRoomFromFileAsync directly.
  • DOCX sources are loaded by ServerTextControl, converted to TX, and passed to CreateRoomAsync as a byte array.
  • ExportDocumentAsync returns the current authoritative TX room document.
  • When saving a DOCX source, the sample converts the exported TX document back to WordprocessingML before replacing the source file.

SampleDocumentService hashes the original source. If the file changes outside the room, Save to source reports a conflict instead of overwriting the newer file.

Add additional .tx or .docx files to the Data directory to make them available on the document-library page. Files are copied to build and publish output.

Room and file persistence

The sample uses three related persistence areas:

  • App_Data/CollaborationRooms contains the collaboration package's authoritative TX room documents and metadata.
  • App_Data/SampleCollaborationRooms.json maps source files to their active room IDs so the portal can restore its active-room list.
  • App_Data/DataProtectionKeys contains the ASP.NET Core Data Protection key ring used for room-access tokens.

The configured room retention is 168 hours. Persistence protects the current room state, but it does not automatically update files in Data.

Complete appsettings reference

The collaboration package reads TextControl:Collaboration. The test application also uses TextControl:StartEditorBackend to decide whether it should host the TX Text Control Document Editor backend itself.

Application host

Setting Sample value Purpose
TextControl:StartEditorBackend true (implicit) Registers DocumentEditorWorkerManager and starts the TX Document Editor backend in this process. The key is omitted from the sample file because Program.cs defaults it to true. Set it to false only when the editor is configured to use an externally managed backend.
AllowedHosts * Standard ASP.NET Core host filtering. The wildcard accepts every host header and is convenient for a test app. Restrict it to the deployed host names in production.
Logging:LogLevel:Default Information Sets the default console logging threshold. Use Debug while diagnosing collaboration worker timings or synchronization fallbacks.
Logging:LogLevel:Microsoft.AspNetCore Warning Reduces routine ASP.NET Core request and infrastructure messages while retaining warnings and errors.

The application clears the framework's default logging providers and adds the console provider in Program.cs, so these logging levels control console output.

Collaboration routing

Setting Sample value Purpose
TextControl:Collaboration:HubPath /tx-collaboration/hub Application-relative route mapped to the collaboration SignalR hub. The Tag Helper uses the same route when it connects the browser component.
TextControl:Collaboration:PublicPathBase Empty (implicit) Externally visible path prefix when a reverse proxy removes that prefix before forwarding requests, for example /collaboration. It must begin with / and cannot contain ? or #. Leave it empty when the application is hosted at the site root or ASP.NET Core already sets HttpRequest.PathBase.

For example, if the public URL is https://example.com/collaboration but the proxy forwards requests to the application without /collaboration, add:

{
  "TextControl": {
    "Collaboration": {
      "PublicPathBase": "/collaboration"
    }
  }
}

This prefixes the generated static-asset and SignalR URLs. It does not change the internal HubPath route.

Sharing

Setting Sample value Valid values and behavior
Sharing:Users Ada Lovelace, Grace Hopper, Alan Turing Display names offered by the collaboration bar's invitation picker. This list is presentation and invitation configuration; the consuming application remains responsible for deciding who may access a room.
Sharing:AllowFreeTextUsers true When true, the inviter can enter a display name not present in Users. When false, invitations are limited to predefined names.
Sharing:InvitationLifetimeHours 168 Number of hours before a generated access token expires. Valid range: 1-8760. Existing editor connections are not a reason to reuse expired invitation URLs; generate a new invitation instead.

The protected invitation stores the assigned user name, room ID, expiration, and a unique nonce. The collaboration hub takes the presence name from this protected token, not from an editable query-string value.

TX worker pool

Setting Sample value Valid values and behavior
Workers:WorkerCount 2 Number of isolated TX worker processes. Valid range: 1-32. A room is consistently assigned to one worker by hashing its document ID. Workers are reused across rooms; this is not one worker per document. More workers increase parallel document throughput but also increase process, memory, and CPU overhead.
Workers:QueueCapacityPerWorker 32 Maximum queued operations for each worker. Valid range: 1-4096. The bounded queue prevents unlimited memory growth when requests arrive faster than TX operations complete.
Workers:StartupTimeoutSeconds 30 Maximum time allowed for a worker process to start and connect. Valid range: 5-300 seconds. Increase it only when process startup is consistently slower in the hosting environment.
Workers:RequestTimeoutSeconds 90 Maximum time for one TX worker request. Valid range: 5-600 seconds. Long documents or unusually expensive structural comparisons may need more time, but increasing this also delays failure recovery.
Workers:RestartAttempts 1 Number of worker restart and retry attempts after a failed request. Valid range: 0-5. A value of 0 disables retry.
Workers:MaxMessageSizeMegabytes 128 Maximum named-pipe request or response size. Valid range: 16-1024 MB. The package also raises the SignalR receive limit sufficiently for the corresponding Base64 payload used by defensive client-side fallbacks. This is a limit, not preallocated memory.
Workers:DotNetHostPath Empty (implicit) Optional path to the dotnet executable used to launch isolated workers. Leave empty to use the current/default .NET host. Configure it when the hosting environment requires a specific runtime path.

Each worker serializes its own TX operations because ServerTextControl contains process-level critical sections. Different rooms assigned to different workers can be processed concurrently. If the queues are regularly saturated, first inspect full-update frequency and TX operation duration before increasing WorkerCount or queue capacity.

Synchronization

Setting Sample value Valid values and behavior
Synchronization:DocumentAccessMode ServerSide ServerSide reads and applies editor ranges through the TX WebSocket handler in the application process. ClientSide uses asynchronous TX JavaScript calls and transports TX selections or complete documents through SignalR.
Synchronization:DirectEditorAccessEnabled true Operational kill switch for direct WebSocket-handler access. It affects only ServerSide mode. If disabled or if an editor connection cannot be registered, synchronization uses the client transport recovery path.
Synchronization:FragmentUploadsEnabled true Allows changed TX ranges to be captured or uploaded as fragments. Disabling it makes normal synchronization rely more heavily on complete-document commits and is intended mainly for diagnosis or compatibility recovery.
Synchronization:CommitIdleMilliseconds 400 Quiet period after the latest edit before a pending change is committed. Valid range: 250-10000 ms. Lower values feel more immediate but create more commits during short typing pauses; higher values reduce request frequency but increase collaboration latency. Starting to type again restarts the idle timer.
Synchronization:ReconciliationIntervalSeconds 25 Base idle interval between complete authoritative verification passes. Valid range: 10-300 seconds. Reconciliation detects edits missed by the normal event/fragment path. A lower value finds mismatches sooner but performs more complete-document work.
Synchronization:MaximumReconciliationIntervalSeconds 300 Maximum adaptive interval after consecutive successful reconciliations. Valid range: the configured base interval through 1800 seconds. New edits, reconnects, and mismatches reset the interval toward the base value.
Synchronization:MaximumFragmentKilobytes 4096 Maximum TX fragment size before synchronization chooses the complete-document fallback. Valid range: 64-65536 KB. Increase it for intentionally large paste or table operations; decrease it to cap individual fragment payloads.
Synchronization:MaximumVersionSnapshots 12 Maximum retained master versions per document for rebasing concurrent edits. Valid range: 2-128. Older versions are discarded first. A client based on a discarded version receives normal full-refresh recovery.
Synchronization:MaximumVersionSnapshotMegabytes 32 Total memory budget for retained version snapshots per document. Valid range: 8-2048 MB. Snapshot count and byte budget are both enforced; whichever limit is reached first removes the oldest history.

The test app's ServerSide mode avoids transferring complete document content through the browser for normal edits. Ordinary paragraph, formatting, and complete-table changes are processed as TX fragments. Structural or ambiguous changes retain the defensive full-document path. Server-side access requires the collaboration hub and TX Document Editor WebSocket handler to run in the same application process. A scaled-out deployment therefore needs sticky routing for both connections.

Reconciliation is intentionally still enabled in the optimized mode. It compares the complete editor document with the authoritative master after an idle period and repairs a mismatch, ensuring that an edit missed by an editor event is not silently lost.

Persistence

Setting Sample value Valid values and behavior
Persistence:Enabled true Selects the package's file-system room store. When false, collaboration rooms are kept only in process and disappear when the application stops.
Persistence:DirectoryPath App_Data/CollaborationRooms Directory containing authoritative TX masters and room metadata. A relative path is resolved from the application content root; an absolute path is used as given. The application identity needs read/write access.
Persistence:RoomRetentionHours 168 Inactivity period before a persisted room expires. Valid range: 1-8760 hours. Connected rooms are not removed by cleanup.
Persistence:CleanupIntervalMinutes 30 Frequency of expired-room cleanup. Valid range: 1-1440 minutes. This controls how soon an already-expired room is discovered, not its retention deadline.
Persistence:FlushDelayMilliseconds 1000 Quiet period before the newest accepted room version is written to storage. Valid range: 0-10000 ms. Updates are broadcast immediately; repeated writes during this window are coalesced. Pending writes are flushed during graceful application shutdown.

Room persistence is not source-file persistence. It protects and restores the live TX master under App_Data/CollaborationRooms, but only Save to source updates the .tx or .docx file in Data.

Environment-variable overrides

ASP.NET Core configuration can override any setting without editing appsettings.json. Use double underscores in environment-variable names. For example, in PowerShell:

$env:TextControl__StartEditorBackend = "false"
$env:TextControl__Collaboration__Workers__WorkerCount = "4"
$env:TextControl__Collaboration__Synchronization__CommitIdleMilliseconds = "500"
dotnet run --project tests/TXTextControl.Web.Collaboration.TestApp

Invalid collaboration values fail validation during application startup with a message containing the full configuration key and accepted range.

Package-consumer setup

The application shows the minimum package integration in Program.cs:

builder.Services.AddTXTextControlCollaboration(
    builder.Configuration.GetSection(TxTextControlCollaborationOptions.DefaultSectionName));
builder.Services.AddHostedService<DocumentEditorWorkerManager>();

app.UseWebSockets();
app.UseTXWebSocketMiddleware();
app.MapTxTextControlCollaboration();

Views/_ViewImports.cshtml registers the collaboration Tag Helper. The room view then connects the package and editor without a manual collaboration script reference:

<tx-collaboration room-token="@Model.AccessToken" />

<div data-tx-collaboration-editor>
    @Html.TXTextControl()
        .TextControl(settings => settings.Dock = TXTextControl.Web.DockStyle.Fill)
        .Render()
</div>

The Tag Helper renders the internal web component and adds the versioned collaboration JavaScript and stylesheet automatically.

Test the packed NuGet package

The project consumes the collaboration source project by default. To test a packed package instead, configure a package source containing the package and run:

dotnet run --project tests/TXTextControl.Web.Collaboration.TestApp `
  -p:UsePackedCollaborationPackage=true `
  -p:CollaborationPackageVersion=34.0.0-alpha

Diagnostic endpoints

The test app includes small endpoints used by integration checks:

  • /_test/services lists registered hosted services.
  • /_test/resolve confirms that ITxTextControlCollaboration resolves.
  • /_test/collaboration/{roomId} reports whether an authoritative room document can be exported and returns its byte length.

These endpoints are test conveniences and are not part of the package's public API.

About

This ASP.NET Core application is a runnable integration sample for `TXTextControl.Web.Collaboration`.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages