{"id":19977774,"url":"https://github.com/uipath/coreipc","last_synced_at":"2025-10-23T21:33:04.055Z","repository":{"id":42428964,"uuid":"200060196","full_name":"UiPath/coreipc","owner":"UiPath","description":"WCF-like service model API for communication over named pipes, TCP and web sockets. .NET and node.js clients.","archived":false,"fork":false,"pushed_at":"2024-12-12T11:33:20.000Z","size":170905,"stargazers_count":30,"open_issues_count":6,"forks_count":9,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-01-12T10:10:17.017Z","etag":null,"topics":["ipc","json-rpc","netcore","rpc","wcf"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UiPath.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-01T13:55:27.000Z","updated_at":"2024-07-01T20:58:05.000Z","dependencies_parsed_at":"2023-02-16T09:45:33.625Z","dependency_job_id":"0e154618-90cb-443b-876d-d3a8a9844a24","html_url":"https://github.com/UiPath/coreipc","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fcoreipc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fcoreipc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fcoreipc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UiPath%2Fcoreipc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UiPath","download_url":"https://codeload.github.com/UiPath/coreipc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241411542,"owners_count":19958753,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ipc","json-rpc","netcore","rpc","wcf"],"created_at":"2024-11-13T03:29:14.336Z","updated_at":"2025-10-23T21:33:04.050Z","avatar_url":"https://github.com/UiPath.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# UiPath.Ipc\n\n[![Build Status](https://uipath.visualstudio.com/CoreIpc/_apis/build/status/CI?branchName=master)](https://uipath.visualstudio.com/CoreIpc/_build?definitionId=637)\n[![NuGet Package](https://img.shields.io/badge/NuGet-UiPath.Ipc-blue)](https://uipath.visualstudio.com/Public.Feeds/_artifacts/feed/UiPath-Internal/NuGet/UiPath.Ipc/overview/2.5.1-20250714-01)\n[![NPM Package](https://img.shields.io/badge/NPM-coreipc-red)](https://github.com/UiPath/coreipc/pkgs/npm/coreipc)\n[![NPM Web Package](https://img.shields.io/badge/NPM-coreipc--web-red)](https://github.com/UiPath/coreipc/pkgs/npm/coreipc-web)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n\n\u003e **Lightweight RPC framework** enabling bidirectional communication with interface-based contracts over **Named Pipes, TCP/IP, and WebSockets**. Supports .NET servers/clients and [Node.js/Web clients](src/Clients/js).\n\n## 🚀 Features\n\n- **🔄 Asynchronous**: Fully async/await compatible API\n- **🔥 One-way Calls**: Fire-and-forget methods (methods returning non-generic `Task`)\n- **📞 Callbacks**: Bidirectional communication with callback interfaces\n- **⚡ Task Scheduling**: Configurable task scheduler support\n- **📡 Multiple Transports**: Named Pipes, TCP/IP, WebSockets or custom transport\n- **🔒 Security**: Client authentication and impersonation for Named Pipes\n- **📦 JSON Serialization**: Built-in JSON serialization with Newtonsoft.Json\n- **🏗️ DI Support**: Integration with Microsoft.Extensions.DependencyInjection\n- **⏰ Cancellation \u0026 Timeouts**: Comprehensive cancellation token and timeout support\n- **🔄 Auto-reconnect**: Broken connections are re-established transparently; you keep using the same proxy instance.\n- **🛡️ Interception**: BeforeConnect, BeforeIncommingCall and BeforeOutgoingCall interception capabilities\n- **📊 Stream Access**: Direct access to underlying transport streams\n- **🌐 Cross-platform**: .NET 6, .NET Framework 4.6.1, and .NET 6 Windows support\n\n## 📦 Installation\n\n```bash\ndotnet add package UiPath.Ipc\n```\n\n## 🏃‍♂️ Quick Start\n\n### 1. Define Your Service Contract\n\n```csharp\npublic interface IComputingService\n{\n    Task\u003cfloat\u003e AddFloats(float x, float y, Message m = null!, CancellationToken ct = default);\n    Task\u003cbool\u003e Wait(TimeSpan duration, CancellationToken ct = default);\n}\n\npublic interface IComputingCallback\n{\n    Task\u003cstring\u003e GetThreadName();\n}\n```\n\n### 2. Implement Your Service\n\n```csharp\npublic sealed class ComputingService : IComputingService\n{\n    public async Task\u003cfloat\u003e AddFloats(float a, float b, Message m = null!, CancellationToken ct = default)\n    {\n        return a + b;\n    }\n\n    public async Task\u003cbool\u003e Wait(TimeSpan duration, CancellationToken ct = default)\n    {\n        await Task.Delay(duration, ct);\n        return true;\n    }\n}\n```\n\n### 3. Create and Start the Server\n\n\u003e Creating a server is done by instantiating the `IpcServer` class, setting its properties and calling the `Start` method.\n\n```csharp\nawait using var serviceProvider = new ServiceCollection()\n    .AddScoped\u003cIComputingService, ComputingService\u003e()\n    .BuildServiceProvider();\n\nawait using var server = new IpcServer\n{\n    Transport = new NamedPipeServerTransport { PipeName = \"computing\" },\n    ServiceProvider = serviceProvider,\n    Endpoints = new() { typeof(IComputingService) }\n};\nserver.Start();\nawait server.WaitForStart();\n```\n\n### 3. Create the Client\n\n\u003e Creating a client is done by 1st implementing all the callback interfaces you'll want to expose as a client:\n\n```csharp\npublic sealed class ComputingCallback : IComputingCallback\n{\n    public Task\u003cstring\u003e GetThreadName() =\u003e Task.FromResult(Thread.CurrentThread.Name);\n}\n```\n\nand then instantiating the `IpcClient`, setting its properties, obtaining a proxy via the `GetProxy\u003cT\u003e` method and using that proxy.\n\n```csharp\nawait using var serviceProvider = new ServiceCollection()\n    .AddScoped\u003cIComputingCallback, ComputingCallback\u003e()\n    .BuildServiceProvider();\n\nvar client = new IpcClient\n{\n    Transport = new NamedPipeClientTransport { PipeName = \"computing\" },\n    ServiceProvider = serviceProvider,\n    Callbacks = new() { typeof(IComputingCallback) }\n}\n\nvar computingService = client.GetProxy\u003cIComputingService\u003e();\nvar three = await computingService.AddFloats(1, 2);\n```\n\n## 🔧 Advanced Features\n\n### Callbacks and Bidirectional Communication\n\n```csharp\npublic class ComputingCallback : IComputingCallback\n{\n    public async Task\u003cstring\u003e GetThreadName()\n    {\n        return Thread.CurrentThread.Name ?? \"Unknown\";\n    }\n\n    public async Task\u003cint\u003e AddInts(int x, int y)\n    {\n        return x + y;\n    }\n}\n\n// Server can call back to client\npublic async Task\u003cstring\u003e GetCallbackThreadName(TimeSpan waitOnServer, Message message, CancellationToken cancellationToken)\n{\n    await Task.Delay(waitOnServer, cancellationToken);\n    return await message.Client.GetCallback\u003cIComputingCallback\u003e().GetThreadName();\n}\n```\n\n### Dependency Injection Integration\n\n```csharp\nvar services = new ServiceCollection()\n    .AddLogging(builder =\u003e builder.AddConsole())\n    .AddSingleton\u003cIComputingService, ComputingService\u003e()\n    .AddSingleton\u003cISystemService, SystemService\u003e()\n    .BuildServiceProvider();\n\nvar ipcServer = new IpcServer\n{\n    ServiceProvider = services,\n    // ... other configuration\n};\n```\n\n### Custom Task Scheduling\n\n```csharp\nvar ipcServer = new IpcServer\n{\n    Scheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler,\n    // ... other configuration\n};\n```\n\n## 🧩 Notable Types\n\n### 1. The `IpcServer`, `IpcClient` and `IpcBase` classes.\n\n\u003e This hierarchy is used for creating and hosting servers and clients respectively.\n\n\u003e ```csharp\n\u003e public abstract class IpcBase { ... }\n\u003e public sealed class IpcServer : IpcBase { ... }\n\u003e public sealed class IpcClient : IpcBase { ... }\n\u003e ```\n\n![IpcServer and IpcClient diagram](readme/diagram.svg)\n\n#### i. `IpcBase`\n\n\u003e This class defines the settings shared between servers and clients.\n\n| Property | Type | Notes |\n| -------- | ---- | ----- |\n| ServiceProvider | IServiceProvider? | **Optional**, defaults to **null**: Resolves services when handling incomming calls. |\n| Scheduler | TaskScheduler? |  **Optional**, defaults to the thread pool: Schedules incomming calls. |\n| RequestTimeout | TimeSpan? | **Optional**, defaults to infinity: Interval after which the honoring of requests will time out. |\n\n\n#### ii. `IpcServer`\n\n**Declared properties**\n\n| Property | Type | Notes |\n| -------- | ---- | ----- |\n| Endpoints | ContractCollection  | **Required**: The collection of `ContractSettings`, which specifies the services to be exposed over Ipc. |\n| Transport | ServerTransport |  **Required**: The server's transport, meaning whether it accepts connection over Named Pipes, TCP/IP, WebSockets, or a custom communication mechanism. |\n\n**Methods**\n\n| Method | Description |\n| ------ | ----------- |\n| `void Start()` | This method starts hosting the current `IpcServer` instance, meaning that it's imminent the transport will start listening and accepting connections, and those connections' calls will start to be honored. \u003cbr /\u003e \u003cbr /\u003e It's thread-safe, idempotent and fire\u0026forget in nature, meaning it doesn't wait for the listener to become active. Further changes to the otherwise mutable `IpcServer` instance  have no effect on the listener's settings or its exposed service collection. \u003cbr /\u003e \u003cbr /\u003e Exceptions: \u003cbr /\u003e- `InvalidOperationException`: wrong configurations, such a `null` or invalid transport.\u003cbr /\u003e- `ObjectDisposedException`: the `IpcServer` instance had been disposed. |\n| `Task WaitForStart()` | This method calls `Start` and then awaits for the connection accepter to start. It's thread-safe and idempotent. |\n| `ValueTask DisposeAsync()` | Stops the connection accepter and cancels all active connections before completing the returned `ValueTask`. |\n\n\u003chr /\u003e\n\n#### iii. `IpcClient`\n\n**Declared properties*\n\n| Property | Type | Notes |\n| -------- | ---- | ----- |\n| Callbacks | ContractCollection  | **Optional**: The collection of `ContractSettings`, which specifies the services to be exposed over Ipc **as callbacks**. |\n| Transport | ClientTransport |  **Required**: The client's transport, meaning whether it connects to the server over Named Pipes, TCP/IP, WebSockets, or a custom communication mechanism. |\n\n**Methods**\n\n| Method | Notes |\n| ------ | ----- |\n| `TProxy GetProxy\u003cTProxy\u003e() where TProxy : class` | Returns an Ipc proxy of the specified type, which is the gateway for remote calling. This method is idempotent, meaning that it will cache its result. |\n\n### 2. The `ContractCollection` and `ContractSettings` classes.\n\n#### i. `ContractCollection`\n\n\u003e `ContractCollection` is a type-safe collection that holds `ContractSettings` instances, mapping service interface types to their configuration. It implements `IEnumerable\u003cContractSettings\u003e` and provides convenient `Add` methods for different scenarios.\n\n**Add Methods:**\n\n| Method | Description |\n| ------ | ----------- |\n| `Add(Type contractType)` | Adds a contract type that will be resolved from the service provider when needed (deferred resolution). |\n| `Add(Type contractType, object? instance)` | Adds a contract type with a specific service instance. If `instance` is `null`, uses deferred resolution. |\n| `Add(ContractSettings endpointSettings)` | Adds a pre-configured `ContractSettings` instance directly. |\n\n#### ii. `ContractSettings`\n\n\u003e `ContractSettings` represents the configuration for a single service contract, including how the service instance is created/resolved, task scheduling, and call interception.\n\n**Properties:**\n\n| Property | Type | Description |\n| -------- | ---- | ----------- |\n| `Scheduler` | `TaskScheduler?` | **Optional**: Custom task scheduler for this specific contract. Inherits from `IpcBase.Scheduler` if not set. |\n| `BeforeIncomingCall` | `BeforeCallHandler?` | **Optional**: Interceptor called before each incoming method call on this contract. |\n\n**Constructors:**\n\n| Constructor | Description |\n| ----------- | ----------- |\n| `ContractSettings(Type contractType, object? serviceInstance = null)` | Creates settings for a contract type with optional direct service instance. If `serviceInstance` is `null`, uses deferred resolution. |\n| `ContractSettings(Type contractType, IServiceProvider serviceProvider)` | Creates settings for a contract type with explicit service provider for dependency injection. |\n\n**Service Resolution Strategies:**\n\n- **Direct Instance**: When you provide a service instance, that exact instance is used for all calls\n- **Deferred Resolution**: When no instance is provided, the service is resolved from the `IpcServer`'s `ServiceProvider` when needed\n- **Injected Resolution**: When you provide a specific `IServiceProvider`, services are resolved from that provider\n\n**Usage Examples:**\n\n```csharp\n// Direct instance\nvar settings1 = new ContractSettings(typeof(IComputingService), new ComputingService());\n\n// Deferred resolution (will use IpcServer.ServiceProvider)\nvar settings2 = new ContractSettings(typeof(IComputingService));\n\n// Custom service provider\nvar customProvider = new ServiceCollection()\n    .AddTransient\u003cIComputingService, ComputingService\u003e()\n    .BuildServiceProvider();\nvar settings3 = new ContractSettings(typeof(IComputingService), customProvider);\n\n// With advanced configuration\nvar settings4 = new ContractSettings(typeof(IComputingService))\n{\n    Scheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler,\n    BeforeIncomingCall = async (callInfo, ct) =\u003e\n    {\n        Console.WriteLine($\"Calling {callInfo.Method.Name}\");\n    }\n};\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuipath%2Fcoreipc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuipath%2Fcoreipc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuipath%2Fcoreipc/lists"}