Skip to content

Commit 9a8c371

Browse files
committed
Change client method for waiting for data
Exceptionhandling instead of null when it times out. Gives better controll on how to handle timeouts. Update v1.1.4.4 on nuget also
1 parent dd6b2fc commit 9a8c371

File tree

10 files changed

+93
-24
lines changed

10 files changed

+93
-24
lines changed

Client/Program.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Text;
6+
using System.Threading;
67
using System.Threading.Tasks;
78

89
namespace Client
@@ -11,6 +12,9 @@ class Program
1112
{
1213
static void Main(string[] args)
1314
{
15+
Console.WriteLine("Waiting 2 second before creating and connecting client");
16+
Thread.Sleep(2000);
17+
1418
//Create client with a simple event for disconnect
1519
var client = new SimpleCrossFrameworkIPC.Client<IMySimpleService>();
1620
client.ClientDisconnected += (sndr, arguments) =>
@@ -39,6 +43,27 @@ static void Main(string[] args)
3943
//Disconnect the client
4044
client.Disconnect();
4145
Console.WriteLine($"Connectionstate: {client.IsConnected()}");
46+
47+
//Testing new client with a different timeout
48+
//Create client with a simple event for disconnect
49+
Console.WriteLine("Test timeout for clients, max 3 waittime for 4 second function");
50+
var client2 = new SimpleCrossFrameworkIPC.Client<IMySimpleService>(3000);
51+
client2.ClientDataReceiveTimeout += (sndr, arguments) =>
52+
Console.WriteLine("Client did not receive data in the given time set");
53+
try
54+
{
55+
//Connect and give state of connection, return values
56+
client2.Connect(Channel.Name, Channel.TimeoutMS);
57+
var proxy = client2.GetProxy();
58+
Console.WriteLine($"DelayedFunction: {proxy.DelayedFunction()}");
59+
}
60+
catch (Exception ex)
61+
{
62+
Console.WriteLine("Error: " + ex.ToString());
63+
}
64+
65+
client2.Disconnect();
66+
4267
Console.WriteLine("Press any key to quit");
4368
Console.ReadLine();
4469
}

Contract/Contract.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ public interface IMySimpleService
1414
int Count { get; set; }
1515

1616
int Function();
17+
bool DelayedFunction();
1718
}
1819

1920
//Simple common class to share name and timeouts
2021
public class Channel
2122
{
2223
public static string Name = "ChannelName";
23-
public static int TimeoutMS = 1000;
24+
public static int TimeoutMS = 1000; //Connection timeout
2425
}
2526
}

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,19 @@ Simple IPC between .net and .core
44
This is a lightversion of a IPC to be used on either .net or .core and even mixed if you like.
55
The "fix" for the conversion is a hack and might not work for later releases.
66

7-
As for 10.05.2020 it works as expected between netstandard 2.0 and .net 4.7.2.
7+
As for 20.09.2020 it works as expected between netstandard 2.0 and .net 4.7.2.
88

99
Class is based on KrakenIPC: https://github.com/darksody/KrakenIPC and Full Duplex Pipes: https://www.codeproject.com/Articles/1179195/Full-Duplex-Asynchronous-Read-Write-with-Named-Pip
1010

11-
1211
## Pipes are old, why did you mesh this up
1312
I had a asp.core application that needed to get data from a .net472 application and the only IPC that actually worked was gRPC ( https://grpc.io/ ).
1413
gRPC was overkill for my project so I wanted something simpler and tiny.
1514

15+
#### Updated 20.09.2020 ####
16+
Added a custom delay for the time to wait for server data for the client.
17+
Changed return method to throw an exception instead of null, to make it easier to handle timeouts in the future.
18+
Also an event is added, to ensure that you catch everything if you decide to suppress exceptions.
19+
1620
## Usage
1721
Server and Client need to share a common interface.
1822
```c#
@@ -49,7 +53,7 @@ Note that this pipe only works on localhost
4953
//Stop server
5054
handler.Stop();
5155
}
52-
catch(Exception ex) //
56+
catch(Exception ex)
5357
{
5458
Console.WriteLine(ex.ToString());
5559
}
@@ -58,20 +62,23 @@ Note that this pipe only works on localhost
5862
When a client connects it will refer to the same interface.
5963
After connection are used to receive data from the server
6064

65+
66+
6167
```c#
62-
var client = new SimpleCrossFrameworkIPC.Client<IMySimpleService>();
68+
int nWaitForServerDataDelay = 2000; //2 sec max waiting for data
69+
var client = new SimpleCrossFrameworkIPC.Client<IMySimpleService>(nWaitForServerDataDelay);
6370

6471
try
6572
{
66-
//Connect with a 1 second timeout
73+
//Connect with a 1 second connection timeout
6774
client.Connect("Channel", 1000);
6875
var proxy = client.GetProxy();
6976

7077
//Print proxy-data to the console
7178
Console.WriteLine("Text: " + proxy.Text);
7279
Console.WriteLine("Number: " + proxy.Number.ToString());
7380
}
74-
catch(Exception ex) //
81+
catch(Exception ex)
7582
{
7683
Console.WriteLine(ex.ToString());
7784
}

Server/Program.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using System.Text;
7+
using System.Threading;
78
using System.Threading.Tasks;
89

910
namespace Server
@@ -13,7 +14,14 @@ public class MySimpleService : IMySimpleService
1314
public int Number { get => 111; }
1415
public string Text { get => "Some string"; }
1516
public int Count { get; set; }
16-
17+
18+
//Simple function to show how to handle the receiveclientTimeout event
19+
public bool DelayedFunction()
20+
{
21+
Thread.Sleep(4000);
22+
return true;
23+
}
24+
1725
public int Function()
1826
{
1927
return Count * 12;

SimpleCrossFrameworkIPC.core/SimpleCrossFrameworkIPC.core.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
55
<SignAssembly>false</SignAssembly>
6-
<Version>1.1.3.2</Version>
6+
<Version>1.1.4.4</Version>
77
<Authors>Lars Werner</Authors>
88
<Description>Simple IPC across .core and .net.</Description>
99
<Copyright>Copyright © 2020</Copyright>
@@ -20,12 +20,12 @@
2020
<PropertyGroup>
2121
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
2222
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
23-
<AssemblyVersion>1.1.3.2</AssemblyVersion>
24-
<FileVersion>1.1.3.2</FileVersion>
23+
<AssemblyVersion>1.1.4.4</AssemblyVersion>
24+
<FileVersion>1.1.4.4</FileVersion>
2525
<AssemblyName>SimpleCrossFrameworkIPC</AssemblyName>
2626
<RootNamespace>SimpleCrossFrameworkIPC</RootNamespace>
2727
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
28-
<PackageIcon>SimpleIPC.jpg</PackageIcon>
28+
<PackageIcon>icon.jpg</PackageIcon>
2929
<PackageLicenseExpression>MIT</PackageLicenseExpression>
3030
<PackageId>SimpleCrossFrameworkIPC</PackageId>
3131
<Product>SimpleCrossFrameworkIPC</Product>
@@ -46,15 +46,15 @@
4646
</ItemGroup>
4747

4848
<ItemGroup>
49-
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
49+
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
5050
<PackageReference Include="System.IO.Pipes" Version="4.3.0" />
5151
<PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
52-
<PackageReference Include="System.Reflection.Emit" Version="4.3.0" />
52+
<PackageReference Include="System.Reflection.Emit" Version="4.7.0" />
5353
<PackageReference Include="Newtonsoft.Json" version="12.0.3" />
5454
</ItemGroup>
5555

5656
<ItemGroup>
57-
<None Include="..\..\..\..\Pictures\SimpleIPC.jpg">
57+
<None Include="..\icon.jpg">
5858
<Pack>True</Pack>
5959
<PackagePath></PackagePath>
6060
</None>

SimpleCrossFrameworkIPC/Client/Client.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,33 @@ public class Client<T> where T : class
3232
//Event if client was disconnected
3333
public event EventHandler<EventArgs> ClientDisconnected;
3434

35+
//Event if client timed out for waiting for data
36+
public event EventHandler<EventArgs> ClientDataReceiveTimeout;
37+
38+
//Timeout variable (in ms) for waiting for data from server. Default 2000 ms (2 secs)
39+
public int ClientReceiveTimeout { get; set; }
40+
3541
//Variable for connection-station
3642
private bool bConnected;
3743

3844
/// <summary>
3945
/// Proxy uses a callbackfunction that builds with the Response-class received from the server
46+
/// Default constructor for 2000 ms wait time for data
4047
/// </summary>
41-
public Client()
48+
public Client() : this(2000)
49+
{
50+
}
51+
52+
/// <summary>
53+
/// Alternative creator for clients
54+
/// </summary>
55+
/// <param name="_ClientReceiveTimeout"></param>
56+
public Client(int _ClientReceiveTimeout)
4257
{
4358
clientPipe = null;
4459
proxy = ProxyHelper.GetInstance<T>(OnMethodCallback);
4560
bConnected = false;
61+
ClientReceiveTimeout = _ClientReceiveTimeout;
4662
}
4763

4864
/// <summary>
@@ -150,8 +166,8 @@ private object OnMethodCallback(string methodName, List<object> parameterValues,
150166
byte[] requestBytes = Encoding.ASCII.GetBytes(json);
151167
clientPipe.WriteBytes(requestBytes, false);
152168

153-
//Wait for data to be received, then build the data (2 seconds max)
154-
responseEvent.Wait(TimeSpan.FromMilliseconds(2000));
169+
//Wait for data to be received, then build the data (user set timeout)
170+
responseEvent.Wait(TimeSpan.FromMilliseconds(ClientReceiveTimeout));
155171
if (responseEvent.IsSet)
156172
{
157173
Message message = JsonConvert.DeserializeObject<Message>(responseJson);
@@ -181,7 +197,10 @@ private object OnMethodCallback(string methodName, List<object> parameterValues,
181197

182198
}
183199
else //If event is not set, then return nada
184-
return null;
200+
{
201+
ClientDataReceiveTimeout?.Invoke(this, new EventArgs());
202+
throw new Exception("Timeout waiting for data");
203+
}
185204
}
186205

187206
/// <summary>

SimpleCrossFrameworkIPC/Common/BasicPipe.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public Task WriteBytes(byte[] bytes, bool InsertLengthFirst = true)
132132
var blength = BitConverter.GetBytes(bytes.Length);
133133
bfull = blength.Concat(bytes).ToArray();
134134
}
135-
135+
136136
return pipeStream.WriteAsync(bfull, 0, bfull.Length);
137137
}
138138

SimpleCrossFrameworkIPC/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.1.3.2")]
36-
[assembly: AssemblyFileVersion("1.1.3.2")]
35+
[assembly: AssemblyVersion("1.1.4.4")]
36+
[assembly: AssemblyFileVersion("1.1.4.4")]

SimpleCrossFrameworkIPC/Server/Server.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Newtonsoft.Json.Linq;
33
using System;
44
using System.Collections.Generic;
5+
using System.IO;
56
using System.IO.Pipes;
67
using System.Linq;
78
using System.Reflection;
@@ -65,11 +66,12 @@ private void CreateServer(string Pipename)
6566

6667
serverPipe.Disconnect += (sndr, args) =>
6768
{
68-
ClientDisconnected?.Invoke(this, new EventArgs());
6969
ServerPipe sender = sndr as ServerPipe;
7070
bool bPipeRemoved = serverPipes.Remove(sender);
7171
if (!bPipeRemoved)
7272
throw new Exception("Pipe not found, rare case ");
73+
else
74+
ClientDisconnected?.Invoke(this, new EventArgs());
7375
};
7476
}
7577

@@ -153,7 +155,14 @@ private void OnMessageReceived(ServerPipe serverPipe, byte[] bytes)
153155
var responseMessage = new Message<Response>(response);
154156
var responseJson = JsonConvert.SerializeObject(responseMessage);
155157
byte[] responseBytes = Encoding.ASCII.GetBytes(responseJson);
156-
serverPipe.WriteBytes(responseBytes, false);
158+
159+
try
160+
{
161+
serverPipe.WriteBytes(responseBytes, false);
162+
}
163+
catch(IOException) //Catch this exception to ensure disconnect
164+
{
165+
}
157166
}
158167
}
159168
}

icon.jpg

14.3 KB
Loading

0 commit comments

Comments
 (0)