Skip to content

Commit 775943e

Browse files
committed
overhaul
1 parent 0072339 commit 775943e

File tree

164 files changed

+2103
-1913
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

164 files changed

+2103
-1913
lines changed

InterReact.Demos/ClientServer/AcceptClient.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public AcceptClient(IRxSocketClient socketClient, ILogger logger)
1616
{
1717
Logger = logger;
1818
SocketClient = socketClient;
19-
ServerResponseMessage = new RequestMessage(NullLoggerFactory.Instance, socketClient, new RingLimiter());
19+
ServerResponseMessage = new RequestMessage(NullLogger<RequestMessage>.Instance , socketClient, new RingLimiter());
2020
ServerRequestMessages = socketClient
2121
.ReceiveAllAsync
2222
.ToObservableFromAsyncEnumerable()
+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
global using System;
1+
global using InterReact;
2+
global using Microsoft.Extensions.Logging;
3+
global using System;
24
global using System.Collections.Generic;
35
global using System.Linq;
46
global using System.Reactive.Linq;
57
global using System.Threading.Tasks;
6-
global using InterReact;
7-
global using Microsoft.Extensions.Logging;

InterReact.Demos/ClientServer/Client.cs

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Diagnostics;
2+
using System.Net;
23

34
namespace ClientServer;
45

@@ -13,16 +14,18 @@ private Client(IInterReactClient irClient, ILogger logger)
1314
Logger = logger;
1415
}
1516

16-
public static async Task<Client> CreateAsync(int port, ILogger logger, ILogger libLogger)
17+
public static async Task<Client> CreateAsync(IPEndPoint ipEndPoint, ILogger logger, ILogger libLogger)
1718
{
18-
IInterReactClient irClient = await new InterReactClientConnector()
19-
.WithLoggerFactory(libLogger.ToLoggerFactory())
20-
.WithPort(port)
21-
.ConnectAsync();
19+
IInterReactClient client = await InterReactClient.ConnectAsync(options =>
20+
{
21+
options.Logger = libLogger;
22+
options.TwsIpAddress = ipEndPoint.Address.ToString();
23+
options.TwsPortAddress = ipEndPoint.Port.ToString();
24+
});
2225

2326
logger.LogCritical("Connected to server.");
2427

25-
return new Client(irClient, logger);
28+
return new Client(client, logger);
2629
}
2730

2831
public void SendControlMessage(string message) => IRClient.Request.RequestControl(message);
@@ -58,7 +61,7 @@ public async Task MeasurePerformance()
5861

5962
public async ValueTask DisposeAsync()
6063
{
61-
Logger.LogCritical("Disconnecting.");
64+
Logger.LogCritical("Disconnecting...");
6265
await IRClient.DisposeAsync();
6366
Logger.LogCritical("Disconnected.");
6467
}

InterReact.Demos/ClientServer/ClientServer.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net7.0</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
66
<Nullable>enable</Nullable>
77
<DebugType>embedded</DebugType>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
11+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
1212
</ItemGroup>
1313

1414
<ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace ClientServer;
2+
3+
internal sealed class FactoryLogger : ILoggerFactory
4+
{
5+
private readonly ILogger Logger;
6+
internal FactoryLogger(ILogger logger) => Logger = logger;
7+
8+
public void AddProvider(ILoggerProvider provider) => throw new NotImplementedException();
9+
10+
// Does not actually create a logger of categoryName.
11+
// Just returns the logger passed to the constructor.
12+
public ILogger CreateLogger(string ignoredCategoryName) => Logger;
13+
14+
public void Dispose() { }
15+
}
16+
17+
public static partial class Extension
18+
{
19+
public static ILoggerFactory ToLoggerFactory(this ILogger logger) => new FactoryLogger(logger);
20+
}

InterReact.Demos/ClientServer/Program.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ public static async Task Main()
66
{
77
Console.Title = "InterReact";
88

9-
ConsoleLogger clientLogger = new("Client: ", LogLevel.Trace, ConsoleColor.DarkYellow);
10-
ConsoleLogger serverLogger = new("Server: ", LogLevel.Trace, ConsoleColor.DarkMagenta);
9+
ConsoleLogger clientLogger = new("Client: ", LogLevel.Trace, ConsoleColor.DarkYellow);
10+
ConsoleLogger serverLogger = new("Server: ", LogLevel.Trace, ConsoleColor.DarkMagenta);
1111
ConsoleLogger clientLibLogger = new("ClientLib: ", LogLevel.Information, ConsoleColor.DarkGreen);
1212
ConsoleLogger serverLibLogger = new("ServerLib: ", LogLevel.Information, ConsoleColor.DarkCyan);
1313

1414
Server server = new(serverLogger, serverLibLogger);
15-
16-
Client client = await Client.CreateAsync(server.IPEndPoint.Port, clientLogger, clientLibLogger);
15+
Client client = await Client.CreateAsync(server.IPEndPoint, clientLogger, clientLibLogger);
1716

1817
await client.MeasurePerformance();
1918
//client.SendControlMessage("Dispose");

InterReact.Demos/ClientServer/Server.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ public sealed class Server : IAsyncDisposable
1212
public Server(ILogger logger, ILogger libLogger)
1313
{
1414
Logger = logger;
15-
15+
1616
// Create the server on an available port on the local host.
17-
SocketServer = RxSocketServer.Create(libLogger);
17+
SocketServer = RxSocketServer.Create(libLogger.ToLoggerFactory());
1818

1919
// The default EndPoint is type IPEndPoint.
2020
IPEndPoint = (IPEndPoint)SocketServer.LocalEndPoint;
@@ -36,7 +36,7 @@ public Server(ILogger logger, ILogger libLogger)
3636

3737
public async ValueTask DisposeAsync()
3838
{
39-
Logger.LogCritical("Disconnecting.");
39+
Logger.LogCritical("Disconnecting...");
4040
await SocketServer.DisposeAsync();
4141
Logger.LogCritical("Disconnected.");
4242
}

InterReact.Demos/ClientServer/ServerRequestMessage.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace ClientServer;
22

3-
public static class Extension
3+
public static partial class Extension
44
{
55
public static IObservable<ServerRequestMessage> ToServerRequestMessages(this IObservable<string[]> source)
66
=> source.Select(strings => new ServerRequestMessage(strings));

InterReact.Demos/HelloWorld/HelloWorld.csproj

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net7.0</TargetFramework>
5+
<TargetFramework>net6.0</TargetFramework>
66
<Nullable>enable</Nullable>
77
<DebugType>embedded</DebugType>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
12-
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
11+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
1312
</ItemGroup>
1413

1514
<ItemGroup>

InterReact.Demos/HelloWorld/Program.cs

+8-11
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,22 @@
1313
using System.Threading.Tasks;
1414

1515
// Create a logger which will write messages to the console.
16-
ILoggerFactory loggerFactory = LoggerFactory
17-
.Create(builder => builder
18-
.AddSimpleConsole(c => c.SingleLine = true)
19-
.SetMinimumLevel(LogLevel.Debug));
16+
ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder
17+
.AddSimpleConsole(c => c.SingleLine = true)
18+
.SetMinimumLevel(LogLevel.Debug));
2019

2120
// Create the InterReact client by connecting to TWS/Gateway on your local machine.
22-
IInterReactClient client = await new InterReactClientConnector()
23-
.WithLoggerFactory(loggerFactory)
24-
.ConnectAsync();
21+
IInterReactClient client = await InterReactClient.ConnectAsync(options => options.LogFactory = loggerFactory);
2522

26-
if (!client.Connection.RemoteIpEndPoint.Port.IsIBDemoPort())
23+
if (!client.RemoteIpEndPoint.Port.IsIBDemoPort())
2724
{
2825
Console.WriteLine("Demo account is required since an order will be placed. Please first login to the TWS demo account.");
2926
return;
3027
}
3128

3229
Contract contract = new()
3330
{
34-
SecurityType = SecurityType.Stock,
31+
SecurityType = ContractSecurityType.Stock,
3532
Symbol = "IBKR",
3633
Currency = "USD",
3734
Exchange = "SMART"
@@ -61,8 +58,8 @@
6158
// Create the order.
6259
Order order = new()
6360
{
64-
OrderAction = OrderAction.Buy,
65-
OrderType = OrderType.Limit,
61+
Action = OrderAction.Buy,
62+
OrderType = OrderTypes.Limit,
6663
LimitPrice = askPriceTick.Price + .50,
6764
TotalQuantity = 100,
6865
};

InterReact.Demos/TicksWpf/MainWindow.xaml.cs

+11-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Reactive.Disposables;
99
using System.Reactive.Linq;
1010
using System.Reactive.Subjects;
11+
using System.Threading;
1112
using System.Windows;
1213
using System.Windows.Media;
1314

@@ -116,7 +117,7 @@ private async void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
116117
{
117118
try
118119
{
119-
Client = await new InterReactClientConnector().ConnectAsync();
120+
Client = await InterReactClient.ConnectAsync();
120121
}
121122
catch (Exception exception)
122123
{
@@ -152,19 +153,21 @@ private async void UpdateSymbol(string symbol)
152153
Contract contract = new()
153154
{
154155
Symbol = symbol,
155-
SecurityType = SecurityType.Stock,
156+
SecurityType = ContractSecurityType.Stock,
156157
Currency = "USD",
157158
Exchange = "SMART"
158159
};
159160

161+
CancellationTokenSource cts = new();
162+
cts.CancelAfter(TimeSpan.FromSeconds(2));
163+
160164
try
161165
{
162-
List<ContractDetails> cds = await Client!
166+
IList<ContractDetails> cds = await Client!
163167
.Service
164-
.GetContractDetailsAsync(contract)
165-
.WaitAsync(TimeSpan.FromSeconds(2));
168+
.GetContractDetailsAsync(contract, cts.Token);
166169

167-
ContractDetails cd = cds.First();
170+
ContractDetails cd = cds.First();
168171

169172
// Display the stock name.
170173
Description = cd.LongName;
@@ -186,7 +189,7 @@ private async void UpdateSymbol(string symbol)
186189
private void SubscribeToTicks(Contract contract)
187190
{
188191
// Create the observable which will emit realtime updates.
189-
IConnectableObservable<object> ticks = Client!
192+
IConnectableObservable<IHasRequestId> ticks = Client!
190193
.Service
191194
.CreateTickObservable(contract)
192195
.ObserveOnDispatcher()
@@ -197,7 +200,7 @@ private void SubscribeToTicks(Contract contract)
197200
TicksConnection = ticks.Connect();
198201
}
199202

200-
private void SubscribeToTicks(IObservable<object> ticks)
203+
private void SubscribeToTicks(IObservable<IHasRequestId> ticks)
201204
{
202205
ticks.Subscribe(onNext: _ => { }, onError: exception => MessageBox.Show($"Fatal: {exception.Message}"));
203206
ticks.OfTickClass(t => t.Alert).Subscribe(alert => MessageBox.Show($"{alert.Message}"));

InterReact.Demos/TicksWpf/TicksWpf.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>WinExe</OutputType>
5-
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
5+
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
66
<UseWPF>true</UseWPF>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>

InterReact.Tests/ConnectTests/Arguments/AllArgs.cs

+9-10
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ public AllArgs(ITestOutputHelper output) : base(output) { }
99
[Fact]
1010
public async Task AllArgsTest()
1111
{
12-
InterReactClientConnector connector = new InterReactClientConnector()
13-
.WithLoggerFactory(LogFactory)
14-
.WithIpAddress(IPAddress.IPv6Loopback)
15-
.WithClientId(1234)
16-
.WithMaxRequestsPerSecond(10)
17-
.DoNotUseDelayedTicks();
12+
IInterReactClient client = await InterReactClient.ConnectAsync(options =>
13+
{
14+
options.LogFactory = LogFactory;
15+
options.TwsIpAddress = IPAddress.IPv6Loopback.ToString();
16+
options.TwsClientId = 1234;
17+
options.MaxRequestsPerSecond = 10;
18+
options.UseDelayedTicks = false;
19+
});
1820

19-
IInterReactClient client = await connector.ConnectAsync();
20-
21-
Assert.Equal(IPAddress.IPv6Loopback, client.Connection.RemoteIpEndPoint.Address);
22-
Assert.Equal(1234, client.Connection.ClientId);
21+
Assert.Equal(IPAddress.IPv6Loopback, client.RemoteIpEndPoint.Address);
2322

2423
await client.DisposeAsync();
2524
}

InterReact.Tests/ConnectTests/Arguments/MessageSendRate.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ public MessageSendRate(ITestOutputHelper output) : base(output, LogLevel.Debug)
1010
[Fact]
1111
public async Task SendRateTest()
1212
{
13-
int count = 0;
14-
IInterReactClient client = await new InterReactClientConnector()
15-
.WithLoggerFactory(LogFactory)
16-
.ConnectAsync();
13+
IInterReactClient client = await InterReactClient.ConnectAsync(options =>
14+
options.LogFactory = LogFactory);
1715

16+
int count = 0;
1817
long start = Stopwatch.GetTimestamp();
1918
while (Stopwatch.GetTimestamp() - start < Stopwatch.Frequency)
2019
{

InterReact.Tests/ConnectTests/Assembly.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
global using Xunit.Abstractions;
55

66
// tests will run in sequence
7-
[assembly:CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]
7+
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]

InterReact.Tests/ConnectTests/ConnectTestBase.cs

+12-8
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@ namespace ConnectTests;
44

55
public abstract class ConnectTestBase
66
{
7+
private readonly ITestOutputHelper Output;
78
protected readonly ILoggerFactory LogFactory;
8-
protected readonly Action<string> Write;
9+
protected readonly ILogger Logger;
10+
protected void Write(string format, params object[] args) =>
11+
Output.WriteLine(string.Format(format, args) + Environment.NewLine);
12+
protected void Write(string str) =>
13+
Output.WriteLine(str + Environment.NewLine);
914

10-
protected ConnectTestBase(ITestOutputHelper output, LogLevel logLevel = LogLevel.Debug)
15+
protected ConnectTestBase(ITestOutputHelper output, LogLevel logLevel = LogLevel.Debug, string name = "Test")
1116
{
12-
LogFactory = LoggerFactory
13-
.Create(builder => builder
14-
.AddMXLogger(output.WriteLine)
15-
.SetMinimumLevel(logLevel));
16-
17-
Write = s => output.WriteLine(s + "\r\n");
17+
Output = output;
18+
LogFactory = LoggerFactory.Create(builder => builder
19+
.AddMXLogger(output.WriteLine)
20+
.SetMinimumLevel(logLevel));
21+
Logger = LogFactory.CreateLogger(name);
1822
}
1923
}

InterReact.Tests/ConnectTests/ConnectTests.csproj

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
<ItemGroup>
1212
<ProjectReference Include="..\..\InterReact\InterReact.csproj" />
13-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
14-
<PackageReference Include="MXLogger" Version="2.0.1" />
15-
<PackageReference Include="xunit" Version="2.4.2" />
16-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
14+
<PackageReference Include="MXLogger" Version="2.0.6" />
15+
<PackageReference Include="xunit" Version="2.6.6" />
16+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.6">
1717
<PrivateAssets>all</PrivateAssets>
1818
</PackageReference>
1919
</ItemGroup>

0 commit comments

Comments
 (0)