Skip to content

Commit 8543c81

Browse files
authored
Merge pull request #1 from jacqueskang/develop
1.0.0
2 parents 68a1507 + a88b70f commit 8543c81

35 files changed

+1250
-1
lines changed

.travis.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
language: csharp
2+
mono: none
3+
solution: IpcServiceFramework.sln
4+
dotnet: 2.1.3
5+
dist: trusty
6+
sudo: required
7+
script:
8+
- cd ./src
9+
- dotnet restore
10+
- dotnet build --configuration Release
11+
- dotnet test JKang.IpcServiceFramework.Core.Tests

README.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,84 @@
1+
[![Build Status](https://travis-ci.org/jacqueskang/IpcServiceFramework.svg?branch=develop)](https://travis-ci.org/jacqueskang/IpcServiceFramework)
2+
13
# IpcServiceFramework
2-
.NET Core Inter-process communication framework
4+
5+
A .NET Core lightweight inter-process communication framework allowing invoking a service via named pipeline (in a similar way as WCF, which is currently unavailable for .NET Core).
6+
7+
Support using primitive or complexe types in service contract.
8+
9+
Support multi-threading on server side with configurable number of threads.
10+
11+
[ASP.NET Core Dependency Injection framework](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) friendly.
12+
13+
## Usage
14+
1. Create an interface as service contract and package it in an assembly to be shared between server and client.
15+
2. Implement the service and host it in an console or web applciation
16+
3. Invoke the service with framework provided proxy client
17+
18+
## Downloads
19+
20+
IpcServiceFramework is available via NuGet:
21+
22+
- [JKang.IpcServiceFramework.Core](https://www.nuget.org/packages/JKang.IpcServiceFramework.Core/)
23+
- [JKang.IpcServiceFramework.Server](https://www.nuget.org/packages/JKang.IpcServiceFramework.Server/)
24+
- [JKang.IpcServiceFramework.Client](https://www.nuget.org/packages/JKang.IpcServiceFramework.Client/)
25+
26+
## Quick Start:
27+
28+
### Step 1 - Create service contract
29+
```csharp
30+
public interface IComputingService
31+
{
32+
float AddFloat(float x, float y);
33+
}
34+
```
35+
36+
### Step 2: Implement the service
37+
38+
```csharp
39+
class ComputingService : IComputingService
40+
{
41+
public float AddFloat(float x, float y)
42+
{
43+
return x + y;
44+
}
45+
}
46+
```
47+
48+
### Step 3 - Host the service in Console application
49+
50+
```csharp
51+
class Program
52+
{
53+
static void Main(string[] args)
54+
{
55+
// configure DI
56+
IServiceCollection services = ConfigureServices(new ServiceCollection());
57+
58+
// run IPC service host
59+
IpcServiceHostBuilder
60+
.Buid("pipeName", services.BuildServiceProvider())
61+
.Run();
62+
}
63+
64+
private static IServiceCollection ConfigureServices(IServiceCollection services)
65+
{
66+
return services
67+
.AddIpc(options =>
68+
{
69+
options.ThreadCount = 4;
70+
})
71+
.AddService<IComputingService, ComputingService>();
72+
}
73+
}
74+
```
75+
It's possible to host IPC service in web application, please check out the sample project *IpcServiceSample.WebServer*
76+
77+
### Step 4 - Invoke the service from client process
78+
79+
```csharp
80+
var proxy = new IpcServiceClient<IComputingService>("pipeName");
81+
float result = await proxy.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
82+
```
83+
84+
__Please feel free to download, fork and/or provide any feedback!__

src/IpcServiceFramework.sln

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 15
4+
VisualStudioVersion = 15.0.27004.2002
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{03210BFB-17B1-4775-A8A2-D302ECBF2F46}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcServiceSample.ServiceContracts", "IpcServiceSample.ServiceContracts\IpcServiceSample.ServiceContracts.csproj", "{D1ADB92C-B4FB-40DD-911E-46360A23381B}"
9+
EndProject
10+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcServiceSample.ConsoleServer", "IpcServiceSample.ConsoleServer\IpcServiceSample.ConsoleServer.csproj", "{24A3C4D2-95A2-48D9-86F2-648879EC74F4}"
11+
EndProject
12+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IpcServiceSample.ConsoleClient", "IpcServiceSample.ConsoleClient\IpcServiceSample.ConsoleClient.csproj", "{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}"
13+
EndProject
14+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{20913218-C740-42E9-9D17-CAD973B676D0}"
15+
ProjectSection(SolutionItems) = preProject
16+
..\.travis.yml = ..\.travis.yml
17+
..\README.md = ..\README.md
18+
EndProjectSection
19+
EndProject
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JKang.IpcServiceFramework.Client", "JKang.IpcServiceFramework.Client\JKang.IpcServiceFramework.Client.csproj", "{13D724CA-3FEA-49E1-BB6B-365CF9397986}"
21+
EndProject
22+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JKang.IpcServiceFramework.Core", "JKang.IpcServiceFramework.Core\JKang.IpcServiceFramework.Core.csproj", "{58200319-1F71-4E22-894D-7E69E0CD0B57}"
23+
EndProject
24+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JKang.IpcServiceFramework.Server", "JKang.IpcServiceFramework.Server\JKang.IpcServiceFramework.Server.csproj", "{069B416A-B2C6-40D1-80B8-AC9ACA2217E3}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JKang.IpcServiceFramework.Core.Tests", "JKang.IpcServiceFramework.Core.Tests\JKang.IpcServiceFramework.Core.Tests.csproj", "{1EC81913-883B-487C-A3FD-98A80EDE3225}"
27+
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IpcServiceSample.WebServer", "IpcServiceSample.WebServer\IpcServiceSample.WebServer.csproj", "{D57727B9-81F1-439A-AD17-0DB26C8F0523}"
29+
EndProject
30+
Global
31+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
32+
Debug|Any CPU = Debug|Any CPU
33+
Release|Any CPU = Release|Any CPU
34+
EndGlobalSection
35+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
36+
{D1ADB92C-B4FB-40DD-911E-46360A23381B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37+
{D1ADB92C-B4FB-40DD-911E-46360A23381B}.Debug|Any CPU.Build.0 = Debug|Any CPU
38+
{D1ADB92C-B4FB-40DD-911E-46360A23381B}.Release|Any CPU.ActiveCfg = Release|Any CPU
39+
{D1ADB92C-B4FB-40DD-911E-46360A23381B}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{24A3C4D2-95A2-48D9-86F2-648879EC74F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{24A3C4D2-95A2-48D9-86F2-648879EC74F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{24A3C4D2-95A2-48D9-86F2-648879EC74F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{24A3C4D2-95A2-48D9-86F2-648879EC74F4}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{8D54E62A-ECFF-4FFF-B9D1-DB343D456451}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{13D724CA-3FEA-49E1-BB6B-365CF9397986}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{13D724CA-3FEA-49E1-BB6B-365CF9397986}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{13D724CA-3FEA-49E1-BB6B-365CF9397986}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{13D724CA-3FEA-49E1-BB6B-365CF9397986}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{58200319-1F71-4E22-894D-7E69E0CD0B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53+
{58200319-1F71-4E22-894D-7E69E0CD0B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
54+
{58200319-1F71-4E22-894D-7E69E0CD0B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{58200319-1F71-4E22-894D-7E69E0CD0B57}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{069B416A-B2C6-40D1-80B8-AC9ACA2217E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57+
{069B416A-B2C6-40D1-80B8-AC9ACA2217E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
58+
{069B416A-B2C6-40D1-80B8-AC9ACA2217E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
59+
{069B416A-B2C6-40D1-80B8-AC9ACA2217E3}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{1EC81913-883B-487C-A3FD-98A80EDE3225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{1EC81913-883B-487C-A3FD-98A80EDE3225}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{1EC81913-883B-487C-A3FD-98A80EDE3225}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{1EC81913-883B-487C-A3FD-98A80EDE3225}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{D57727B9-81F1-439A-AD17-0DB26C8F0523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{D57727B9-81F1-439A-AD17-0DB26C8F0523}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{D57727B9-81F1-439A-AD17-0DB26C8F0523}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{D57727B9-81F1-439A-AD17-0DB26C8F0523}.Release|Any CPU.Build.0 = Release|Any CPU
68+
EndGlobalSection
69+
GlobalSection(SolutionProperties) = preSolution
70+
HideSolutionNode = FALSE
71+
EndGlobalSection
72+
GlobalSection(NestedProjects) = preSolution
73+
{D1ADB92C-B4FB-40DD-911E-46360A23381B} = {03210BFB-17B1-4775-A8A2-D302ECBF2F46}
74+
{24A3C4D2-95A2-48D9-86F2-648879EC74F4} = {03210BFB-17B1-4775-A8A2-D302ECBF2F46}
75+
{8D54E62A-ECFF-4FFF-B9D1-DB343D456451} = {03210BFB-17B1-4775-A8A2-D302ECBF2F46}
76+
{D57727B9-81F1-439A-AD17-0DB26C8F0523} = {03210BFB-17B1-4775-A8A2-D302ECBF2F46}
77+
EndGlobalSection
78+
GlobalSection(ExtensibilityGlobals) = postSolution
79+
SolutionGuid = {F87E0D46-F461-4E41-9A3B-64710A6DFB2F}
80+
EndGlobalSection
81+
EndGlobal
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\IpcServiceSample.ServiceContracts\IpcServiceSample.ServiceContracts.csproj" />
10+
<ProjectReference Include="..\JKang.IpcServiceFramework.Client\JKang.IpcServiceFramework.Client.csproj" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using IpcServiceSample.ServiceContracts;
2+
using JKang.IpcServiceFramework;
3+
using System;
4+
using System.Threading.Tasks;
5+
6+
namespace IpcServiceSample.ConsoleClient
7+
{
8+
class Program
9+
{
10+
static void Main(string[] args)
11+
{
12+
MainAsync(args).Wait();
13+
}
14+
15+
private static async Task MainAsync(string[] args)
16+
{
17+
try
18+
{
19+
var client = new IpcServiceClient<IComputingService>("pipeName");
20+
21+
// test 1: call IPC service method with primitive types
22+
float result1 = await client.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
23+
Console.WriteLine($"sum of 2 floating number is: {result1}");
24+
25+
// test 1: call IPC service method with complex types
26+
ComplexNumber result2 = await client.InvokeAsync(x => x.AddComplexNumber(
27+
new ComplexNumber(0.1f, 0.3f),
28+
new ComplexNumber(0.2f, 0.6f)));
29+
Console.WriteLine($"sum of 2 complexe number is: {result2.A}+{result2.B}i");
30+
31+
// test 3: call IPC service method without parameter or return
32+
await client.InvokeAsync(x => x.DoNothing());
33+
Console.WriteLine($"invoked DoNothing()");
34+
}
35+
catch (Exception ex)
36+
{
37+
Console.WriteLine(ex);
38+
}
39+
}
40+
}
41+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using IpcServiceSample.ServiceContracts;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace IpcServiceSample.ConsoleServer
5+
{
6+
public class ComputingService : IComputingService
7+
{
8+
private readonly ILogger<ComputingService> _logger;
9+
10+
public ComputingService(ILogger<ComputingService> logger) // inject dependencies in constructor
11+
{
12+
_logger = logger;
13+
}
14+
15+
public ComplexNumber AddComplexNumber(ComplexNumber x, ComplexNumber y)
16+
{
17+
_logger.LogInformation($"{nameof(AddComplexNumber)} called.");
18+
return new ComplexNumber(x.A + y.A, x.B + y.B);
19+
}
20+
21+
public float AddFloat(float x, float y)
22+
{
23+
_logger.LogInformation($"{nameof(AddFloat)} called.");
24+
return x + y;
25+
}
26+
27+
public void DoNothing()
28+
{ }
29+
}
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>netcoreapp2.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\IpcServiceSample.ServiceContracts\IpcServiceSample.ServiceContracts.csproj" />
10+
<ProjectReference Include="..\JKang.IpcServiceFramework.Server\JKang.IpcServiceFramework.Server.csproj" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
15+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
16+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.0.0" />
17+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
18+
</ItemGroup>
19+
20+
</Project>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using IpcServiceSample.ServiceContracts;
2+
using JKang.IpcServiceFramework;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Logging;
5+
using System;
6+
7+
namespace IpcServiceSample.ConsoleServer
8+
{
9+
class Program
10+
{
11+
static void Main(string[] args)
12+
{
13+
// build service provider
14+
IServiceCollection services = ConfigureServices(new ServiceCollection());
15+
ServiceProvider serviceProvider = services.BuildServiceProvider();
16+
17+
// TODO start IPC service host
18+
IpcServiceHostBuilder
19+
.Buid("pipeName", serviceProvider as IServiceProvider)
20+
.Run();
21+
22+
}
23+
24+
private static IServiceCollection ConfigureServices(IServiceCollection services)
25+
{
26+
services
27+
.AddLogging(builder =>
28+
{
29+
builder.AddConsole();
30+
builder.SetMinimumLevel(LogLevel.Debug);
31+
});
32+
33+
services
34+
.AddIpc(options =>
35+
{
36+
options.ThreadCount = 2;
37+
})
38+
.AddService<IComputingService, ComputingService>()
39+
;
40+
41+
return services;
42+
}
43+
}
44+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace IpcServiceSample.ServiceContracts
2+
{
3+
public interface IComputingService
4+
{
5+
float AddFloat(float x, float y);
6+
ComplexNumber AddComplexNumber(ComplexNumber x, ComplexNumber y);
7+
void DoNothing();
8+
}
9+
10+
public class ComplexNumber
11+
{
12+
public float A { get; set; }
13+
public float B { get; set; }
14+
15+
public ComplexNumber(float a, float b)
16+
{
17+
A = a;
18+
B = b;
19+
}
20+
}
21+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<RootNamespace>IpcServiceSample.ServiceContracts</RootNamespace>
6+
</PropertyGroup>
7+
8+
</Project>

0 commit comments

Comments
 (0)