Logo

dev-resources.site

for different kinds of informations.

Inter-process Communication with WitCom

Published at
1/13/2025
Categories
csharp
programming
backenddevelopment
remote
Author
dmitrat
Author
7 person written this
dmitrat
open
Inter-process Communication with WitCom

Working on engineering systems that often involve legacy components, I frequently face challenges in integrating outdated elements with modern platforms. For example, you may encounter scenarios requiring support for obsolete file formats that can only be opened by a 32-bit component. This limitation poses a dilemma: either remain on an outdated platform, foregoing modern framework advantages like 64-bit addressing, or isolate the legacy component’s logic into a separate process with which the main application communicates.

There are numerous scenarios for inter-process communication (IPC) on the same machine, including:

  • Supporting components built for a different platform than the main system.
  • Running multiple parallel, independent processes to overcome system limitations.
  • Enabling data exchange between several concurrently running applications. Many others.

Why WitCom?

For years, I relied on WCF for its flexibility, particularly its support for selecting optimized transports like named pipes for local interactions. However, WCF was no longer fully available when I migrated to .NET Core. While recent .NET versions have reintroduced support for WCF, its current status remains uncertain.

One of WCF’s standout features was ServiceContract, which allows defining a service interface. This approach simplifies development: a client integrating a WCF service generates the required wrapper code automatically, eliminating guesswork about function names or parameters. Unfortunately, both SignalR and gRPC require method calls using plain text method names, complicating code maintenance.

Enter WitCom

A few years ago, I discovered the IpcServiceFramework, which uses interfaces to define services and leverages reflection to unpack and invoke methods on the service side. While promising, the project was no longer maintained. Inspired by its core concept, I developed my own implementation, which evolved into WitCom.

WitCom is a WCF-like communication framework designed for .NET. It enables developers to define service interfaces, choose a transport, and establish full-duplex communication with minimal effort. Supported transports include common options like Named Pipes, TCP, and WebSocket, as well as unique support for memory-mapped files. This enables ultra-fast, low-latency duplex communication on a local machine, ideal for transferring large volumes of data with maximum efficiency.

Example: Inter-process Communication with WitCom

You can find an example implementation in the WitCom GitHub repository.

Step 1: Define the Service Contract

public interface IExampleService
{
    event ExampleServiceEventHandler ProcessingStarted;
    event ExampleServiceProgressEventHandler ProgressChanged;
    event ExampleServiceProcessingEventHandler ProcessingCompleted;

    bool StartProcessing();
    void StopProcessing();
}

public delegate void ExampleServiceEventHandler();
public delegate void ExampleServiceProgressEventHandler(double progress);
public delegate void ExampleServiceProcessingEventHandler(ProcessingStatus status);
Enter fullscreen mode Exit fullscreen mode

WitCom supports full-duplex communication natively using event callbacks, with any delegate type (e.g., PropertyChangedEventHandler) supported.

Step 2: Implement the Service in the Agent

The agent process hosts the service:

public class ExampleService : IExampleService
{
    public event ExampleServiceEventHandler ProcessingStarted = delegate { };
    public event ExampleServiceProgressEventHandler ProgressChanged = delegate { };
    public event ExampleServiceProcessingEventHandler ProcessingCompleted = delegate { };

    private CancellationTokenSource? CancellationTokenSource { get; set; }

    public bool StartProcessing()
    {
        if (CancellationTokenSource != null) return false;

        CancellationTokenSource = new CancellationTokenSource();
        Task.Run(Process);

        ProcessingStarted();
        return true;
    }

    public void StopProcessing()
    {
        CancellationTokenSource?.Cancel();
    }

    private void Process()
    {
        ProcessingStatus status = ProcessingStatus.Success;
        for (int i = 1; i <= 100; i++)
        {
            if (CancellationTokenSource?.IsCancellationRequested == true)
            {
                status = ProcessingStatus.Interrupted;
                break;
            }
            ProgressChanged(i);
            Thread.Sleep(100);
        }

        ProcessingCompleted(status);
        CancellationTokenSource = null;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Start the Agent Process

The host process launches the agent as a separate process, passing the communication address via command-line arguments. For example:

var process = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = "Agent.exe",
        Arguments = "--address=ExampleMemoryMap",
        UseShellExecute = false,
    }
};
process.Start();
Enter fullscreen mode Exit fullscreen mode

Step 4: Start the Server in the Agent

The agent starts the server and listens for connections using the received address:

var server = WitComServerBuilder.Build(options =>
{
    options.WithService(new ExampleService());
    options.WithMemoryMappedFile("ExampleMemoryMap");
    options.WithEncryption();
    options.WithJson();
    options.WithAccessToken("SecureAccessToken");
    options.WithTimeout(TimeSpan.FromSeconds(1));
});
server.StartWaitingForConnection();
Enter fullscreen mode Exit fullscreen mode

Step 5: Create the Client in the Host

The host process connects to the agent:

var client = WitComClientBuilder.Build(options =>
{
    options.WithMemoryMappedFile("ExampleMemoryMap");
    options.WithEncryption();
    options.WithJson();
    options.WithAccessToken("SecureAccessToken");
    options.WithTimeout(TimeSpan.FromSeconds(1));
});

if (!await client.ConnectAsync(TimeSpan.FromSeconds(5), CancellationToken.None))
{
    Console.WriteLine("Failed to connect.");
    return;
}

var service = client.GetService<IExampleService>();
service.ProcessingStarted += () => Console.WriteLine("Processing started!");
service.ProgressChanged += progress => Console.WriteLine($"Progress: {progress}%");
service.ProcessingCompleted += status => Console.WriteLine($"Processing completed: {status}");
Enter fullscreen mode Exit fullscreen mode

Key Advantages of WitCom

  • Service Contracts: Define service interfaces for a clean and maintainable API.
  • Multiple Transports: Choose from Named Pipes, TCP, WebSocket, or memory-mapped files.
  • Full-Duplex Communication: Events and callbacks are natively supported.
  • Encryption: Secure communication with AES/RSA-based encryption.
  • Authorization: Token-based authentication ensures only authorized clients can connect.
  • High Performance: Optimize IPC for the local machine using memory-mapped files.
  • Easy Error Handling: Use WitComExceptionFault to handle communication errors.

Conclusion

WitCom is a robust and modern alternative for inter-process communication in .NET, combining the best features of WCF with modern transport options. For more information, visit WitCom’s documentation and explore examples on GitHub.

csharp Article's
30 articles in total
Favicon
Dynamically Extracting Endpoint Names and Attributes from a Custom C# MVC API
Favicon
Integrating Azure OpenAI with .NET Applications Using Microsoft.Extensions.AI
Favicon
What is Quartz.Net and its simple implementation
Favicon
Beyond the Random Class: Cryptographic Randomness in .NET 6+
Favicon
I am a beginner in Python programming and I want to develop my skills.
Favicon
Demystifying AIContents in Microsoft.Extensions.AI
Favicon
Inter-process Communication with WitCom
Favicon
Mediator Pattern
Favicon
[WPF] Draw Tree Topology
Favicon
Game Dev Digest — Issue #264 - Game Dev Insights: AI Tools, VFX, Optimization & Tutorials
Favicon
Semantic Kernel: Crea un API para Generación de Texto con Ollama y Aspire
Favicon
Building Modern Desktop Applications with .NET 9: Features and Best Practices
Favicon
Orden en el Código .NET
Favicon
Building a Solana Wallet Backend with .NET (Part 1)
Favicon
Top 10 Programming Languages to Learn in 2025 🖥️
Favicon
ИСТОРИЯ .NET
Favicon
dotnet терминал команды
Favicon
Cqrs
Favicon
Why You Should Learn C#/.NET in 2025
Favicon
Custom Middleware Extensions in .NET Core Web API
Favicon
Qt/C++ Senior Experts Provide Customized Software Development Services
Favicon
Static Lambda in C# 12 : Performance Improvement
Favicon
Builder Pattern in C#: Practical Implementation and Examples
Favicon
WitCom: Modernizing Client-Server Communication
Favicon
Permission-Based Authentication and Authorization in .NET, via Cookies
Favicon
Simplifying CRUD Operations Using Primary Constructors for Dependency Injection with Generic Interfaces
Favicon
Entendendo Service, Repository e Controller, PT. 1
Favicon
Take your skills to the next level with these top courses on a HUGE DISCOUNT!
Favicon
Como Resolver o Erro DbUpdateConcurrencyException no Entity Framework
Favicon
Loops vs Recursividade

Featured ones: