Products Technologies Demo Docs Blog Support Company

Load Balancing: Using Different TCP Service Locations using a Custom WebSocketHandler

The Text Control online document editor requires a backend TCP service to synchronize the document rendering. This article explains how to route the synchronization traffic to different servers dynamically using a custom WebSocketHandler.

Load Balancing: Using Different TCP Service Locations using a Custom WebSocketHandler

When deploying the TX Text Control document editor in an ASP.NET Core (.NET 5) Web Application, the synchronization service can be deployed separately to one or more Windows VMs. This can be useful when separating the web application from the Text Control stack for deployment reasons (for example when deploying your web application to Azure App Services running on Linux) or when load balancing the TCP synchronization service separately.

In order to do this, a custom WebSocketMiddleware can be implemented.

What is a WebSocketMiddleware?

TX Text Control uses a WebSocket connection from the browser to an application layer that handles the traffic between the client and the TCP synchronization service. The WebSocketHandler (part of TX Text Control), routes the synchronization calls from and to the TCP service. The WebSocketMiddleware is creating an instance of the WebSocketHandler.

WebSocketHandler

The ASP.NET (Core) MVC NuGet package that is required to implement the document editor comes with a standard, out-of-the-box WebSocketMiddleware that connects to a TCP service that runs on the same machine.

The following class CustomWebSocketMiddleware implements a custom WebSocketMiddleware:

using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using TXTextControl.Web;

public class CustomWebSocketMiddleware {

   private RequestDelegate m_next;
   private IPAddress m_serviceAddress;
   private int m_servicePort;

   // list of available backend TCP services
   internal readonly List<byte[]> DefaultServiceAddress =
      new List<byte[]>() { 
         new byte[] { 127, 0, 0, 2 },
         new byte[] { 127, 0, 0, 1 }
      };

   internal const int DefaultServicePort = 4278;

   public CustomWebSocketMiddleware(RequestDelegate next) {
      m_next = next;
      m_serviceAddress = new IPAddress(DefaultServiceAddress[0]);
      m_servicePort = DefaultServicePort;
   }

   public async Task Invoke(HttpContext context) {
      if (context.WebSockets.IsWebSocketRequest &&
        context.WebSockets.WebSocketRequestedProtocols.Contains("TXTextControl.Web")) {

         // server id from query string (provided in view code)
         int serverId = int.Parse(context.Request.Query["server"]);

         // create a new WebSocketHandler with random server
         var ws = new WebSocketHandler(
            new IPAddress(DefaultServiceAddress[serverId]),
            m_servicePort);

         await ws.Invoke(context);
      }
      else if (m_next != null) {
         await m_next.Invoke(context);
      }
   }
}

As described in a previous blog article, the custom WebSocketMiddleware must be added to the Startup.cs:

app.UseMiddleware<CustomWebSocketMiddleware>();

In the view code, an additional query string is provided to the WebSocketURL property:

@using TXTextControl.Web.MVC

@{
   Random rand = new Random();
   string serverId = rand.Next(0, 2).ToString();

   // build WebSocketURL including a server id in query string
   var sProtocol = (Context.Request.IsHttps) ? "wss://" : "ws://";
   var sWebSocketURL = sProtocol + Context.Request.Host
     + "/TXWebSocket?server=" + serverId;
}

@Html.TXTextControl().TextControl(settings => {
    settings.WebSocketURL = sWebSocketURL;
}).Render()

This workflow is just a simplified idea of what can be done using a custom WebSocketMiddleware. A random value (1 or 0) is passed as a query string to the WebSocketMiddleware. In the WebSocketMiddleware itself, a specific IP is used from a list of IP addresses based on the given random index value from the query string.

// server id from query string (provided in view code)
int serverId = int.Parse(context.Request.Query["server"]);

// create a new WebSocketHandler with random server
var ws = new WebSocketHandler(
  new IPAddress(DefaultServiceAddress[serverId]),
  m_servicePort);

Following this simple workflow, a random load balancer has been implemented that routes the TCP traffic to 2 different servers.

Pro tip

A custom WebSocketMiddleware can be also used to create an instance of the WebSocketHandler without passing a value from the view code. Typically, when changing the IP address of the TCP backend or when providing this IP dynamically.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Angular

Integrate document processing, editing, sharing, collaboration, creation, electronic signatures, and PDF generation into your Angular Web applications.

Learn more about Angular

Related Posts

AngularASP.NETJavaScript

Building an ASP.NET Core Backend Application to Host the Document Editor and…

This article explains how to create an ASP.NET Core backend application to host the Document Editor and Document Viewer. This backend application is required to provide the required functionality…


ASP.NETASP.NET CoreBackend

Deploying the TX Text Control Document Editor Backend Web Server in Docker

This article describes how to deploy the TX Text Control Document Editor backend web server in Docker. The backend web server is a .NET Core application that provides the required synchronization…


ASP.NETASP.NET CoreBackend

Configuring the TX Text Control Document Editor Backend Web Server,…

This article describes how to configure the TX Text Control Document Editor Backend Web Server, including port and logging settings.


ASP.NETASP.NET CoreBackend

Designing a Maintainable PDF Generation Web API in ASP.NET Core (Linux) C#…

This article shows how to create a PDF generation Web API in ASP.NET Core on Linux using TX Text Control .NET Server. The clean architecture is used to create a maintainable and testable solution.


AngularASP.NETBlazor

Building an ASP.NET Core Backend (Linux and Windows) for the Document Editor…

This article shows how to create a backend for the Document Editor and Viewer using ASP.NET Core. The backend can be hosted on Windows and Linux and can be used in Blazor, Angular, JavaScript, and…