Products Technologies Demo Docs Blog Support Company

Synchronizing Editable Regions with SignalR Broadcasting

Editable regions can be used to design documents where different users collaborate on the same document. This article shows how to synchronize these regions over all connected instances using SignalR.

Synchronizing Editable Regions with SignalR Broadcasting

SignalR enables applications to push update information from the server to connected clients. This sample shows how to synchronize changes in editable regions by broadcasting these changes to all clients.

This concept shows how to enable collaboration concepts to TX Text Control based applications. A document can be locked down for editing with exceptions for specific users. These Editable Regions are exceptions for specific users or user groups. The internal TX Text Control user management concept initializes the editor with a specific user name defined through the UserNames property.

Implementing the SignalR Hub

The sample project implements a Hub as the endpoint for SignalR:

public class CollabHub : Hub
{
    public async Task SetEditableRegionSync(EditableRegionSync editableRegionSync)
    {
        await Clients.All.SendAsync("ReceiveRegionSync", editableRegionSync);
    }
}

public class EditableRegionSync
{
    public string User { get; set; }
    public int RegionId { get; set; }
    public string Document { get; set; }
}

The SetEditableRegionSync method accepts an EditableRegionSync object that stores the User, the RegionId and the Document as a Base64 encoded string in the internal TX Text Control format. This method broadcasts this object immediately to all connected clients.

Calling the Hub

The JavaScript function updateSection saves the currently modified region and calls the SignalR endpoint:

function updateSection(region) {

    // check flags
    if (_updating === true || _dirtyFlag === false)
        return;

    TXTextControl.editableRegions.forEach(function (er) {

        // find region by id
        er.getID(function (id) {

            if (region.editableRegion.id == id) {

                // save the region content
                er.save(TXTextControl.StreamType.InternalUnicodeFormat,
                    function (doc) {

                    // create sync object
                    var regionSyncObject = {
                        User: region.editableRegion.userName,
                        RegionId: id, Document: doc.data
                    };

                    // call signalr hub with sync object
                    _connection.invoke("SetEditableRegionSync",
                        regionSyncObject).catch(function (err) {
                            return console.error(err.toString());
                        });

                });

            }

        });
    });
}

This function is called in a JavaScript interval that is cleared when typing, so that the synchronization happens, if the user is in idle mode.

Listening for the Broadcast

If the ReceiveRegionSync message is received from the SignalR hub endpoint, the region is updated by loading the content:

// connect to signalr hub
_connection = new signalR.HubConnectionBuilder().withUrl("/collabHub").build();
_connection.start();

_connection.on("ReceiveRegionSync", async function (syncRegion) {

    // set flag to avoid infinite loops
    _updating = true;

    TXTextControl.editableRegions.forEach(function (er) {

        // find editable region by id
        er.getID(function (id) {

            if (syncRegion.regionId == id) {
                er.getStart(function (start) {
                    er.getLength(function (length) {

                        TXTextControl.inputPosition.getTextPosition(function (sp) {

                            // select editable region
                            var sel = TXTextControl.selection;
                            var bounds = { "start": start - 1, "length": length };
                            sel.setBounds(bounds);

                            //sel = TXTextControl.selection;
                            // load synchronized content
                            sel.load(TXTextControl.StreamType.InternalUnicodeFormat,
                                syncRegion.document);

                            // reset input position
                            var bounds = { "start": sp, "length": 0 };
                            sel.setBounds(bounds);

                            // reset flags
                            setTimeout(function () {
                                _updating = false;
                                _dirtyFlag = false;
                            }, 100);
                        });

                    });
                });
            }
        });
    });
});

Because of the editable region concept, users cannot change other regions and the document will never be out of sync.

The following screen video shows this concept in action with two authors working on their editable regions that are automatically synchronized when the author stops typing.

Test this on your own and download the sample project from our GitHub repository.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Also See

This post references the following in the documentation:

  • Javascript: EditableRegion Object
  • Javascript: FormattedText.editableRegions Property
  • Javascript: InputPosition Object
  • Javascript: Selection Object
  • Javascript: Selection.save Method
  • TXTextControl.Web.MVC.TextControlSettings.UserNames Property

GitHub

Download and Fork This Sample on GitHub

We proudly host our sample code on github.com/TextControl.

Please fork and contribute.

Download ZIP

Open on GitHub

Open in Visual Studio

Requirements for this sample

  • TX Text Control .NET Server X18 (trial sufficient)
  • Visual Studio 2019

Related Posts

JavaScriptASP.NET CoreDocument Editor

Format Painter in ASP.NET Core: Building Custom Text Formatting with TX Text…

This article demonstrates how to build a Format Painter feature using the TX Text Control Document Editor, implementing format detection, copy and paste operations, and custom style handling…


ASP.NETJavaScriptASP.NET Core

Add JavaScript to PDFs with TX Text Control in C# .NET: Time-Based Alerts…

In this article, we explore how to enrich PDF documents with JavaScript using TX Text Control in C# .NET. Read on to learn how to create time-based alerts that trigger actions based on specific…


AngularASP.NETJavaScript

Observe When the Reporting Preview Tab is Active Using MutationObserver

This article shows how to observe when the Reporting Preview tab is active using MutationObserver. The Reporting Preview tab is a feature of the TX Text Control Document Editor that allows you to…


ASP.NETASP.NET CoreCollaboration

Adding and Sharing Annotations across Document Types using the Document…

Learn how to add and share annotations across different document types using the Document Viewer in ASP.NET Core C#. This article shows how to create a simple web application that allows users to…


ASP.NETJavaScriptASP.NET Core

Loading Documents from Azure Blob Storage into the TX Text Control Document…

This article shows how to load documents from Azure Blob Storage into the TX Text Control Document Editor using pure JavaScript. It shows how to create a storage container and how to download…