Skip to content

Commit 8a2435d

Browse files
refactoring: channel creation (#254)
1 parent 7fd6791 commit 8a2435d

5 files changed

Lines changed: 64 additions & 18 deletions

File tree

‎lib/ShortDev.Microsoft.ConnectedDevices.NearShare/NearShareSender.cs‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,13 @@ async Task<SenderStateMachine> PrepareTransferInternalAsync(EndpointInfo endpoin
2121

2222
Guid operationId = Guid.NewGuid();
2323

24-
using var handShakeChannel = await session.StartClientChannelAsync<HandshakeHandler>(cancellationToken).ConfigureAwait(false);
25-
HandshakeHandler handshake = new(handShakeChannel);
24+
var handshake = await session.StartClientChannelAsync<HandshakeHandler>(cancellationToken).ConfigureAwait(false);
2625
await handshake.Execute(operationId).ConfigureAwait(false);
2726

2827
// ToDo: CorrelationVector
2928
// var cv = handshakeResultMsg.Header.TryGetCorrelationVector() ?? throw new InvalidDataException("No Correlation Vector");
3029

31-
var channel = await session.StartClientChannelAsync(operationId.ToString("D").ToUpper(), NearShareApp.Name, cancellationToken).ConfigureAwait(false);
32-
SenderStateMachine senderStateMachine = new(channel);
30+
var senderStateMachine = await session.StartClientChannelAsync<SenderStateMachine>(operationId.ToString("D").ToUpper(), NearShareApp.Name, cancellationToken).ConfigureAwait(false);
3331
return senderStateMachine;
3432
}
3533

@@ -48,7 +46,7 @@ public async Task SendFilesAsync(CdpDevice device, IReadOnlyList<CdpFileProvider
4846
await senderStateMachine.SendFilesAsync(files, progress, cancellationToken).ConfigureAwait(false);
4947
}
5048

51-
sealed class HandshakeHandler(CdpChannel channel) : CdpBondApp(channel), ICdpAppId
49+
sealed class HandshakeHandler(CdpChannel channel) : CdpBondApp(channel), ICdpAppFactory<HandshakeHandler>, ICdpAppId
5250
{
5351
public static string Id { get; } = NearShareHandshakeApp.Id;
5452
public static string Name { get; } = NearShareHandshakeApp.Name;
@@ -76,9 +74,11 @@ protected override void HandleMessage(in BinaryMsgHeader header, ValueSet payloa
7674

7775
_promise.SetResult();
7876
}
77+
78+
static HandshakeHandler ICdpAppFactory<HandshakeHandler>.Create(CdpChannel channel) => new(channel);
7979
}
8080

81-
sealed class SenderStateMachine(CdpChannel channel) : CdpBondApp(channel)
81+
sealed class SenderStateMachine(CdpChannel channel) : CdpBondApp(channel), ICdpAppFactory<SenderStateMachine>
8282
{
8383
readonly TaskCompletionSource _promise = new();
8484
public async Task SendUriAsync(Uri uri)
@@ -199,6 +199,8 @@ void HandleDataRequest(BinaryMsgHeader header, ValueSet payload)
199199
});
200200
}
201201

202+
static SenderStateMachine ICdpAppFactory<SenderStateMachine>.Create(CdpChannel channel) => new(channel);
203+
202204
private readonly struct DataResponseMessage : IBinaryWritable<DataResponseMessage>
203205
{
204206
public required CdpFileProvider FileProvider { get; init; }

‎lib/ShortDev.Microsoft.ConnectedDevices/CdpAppRegistration.cs‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Collections.Concurrent;
2+
using System.Diagnostics.CodeAnalysis;
23

34
namespace ShortDev.Microsoft.ConnectedDevices;
45

@@ -17,6 +18,9 @@ public static class CdpAppRegistration
1718

1819
private static readonly ConcurrentDictionary<string, AppId> _registration = new(StringComparer.OrdinalIgnoreCase);
1920

21+
public static void RegisterApp<TApp>() where TApp : CdpAppBase, ICdpAppFactory<TApp>, ICdpAppId
22+
=> RegisterApp(TApp.Id, TApp.Name, TApp.Create);
23+
2024
public static void RegisterApp<TApp>(CdpAppFactory<TApp> factory) where TApp : CdpAppBase, ICdpAppId
2125
=> RegisterApp(TApp.Id, TApp.Name, factory);
2226

@@ -39,4 +43,25 @@ internal static CdpAppBase InstantiateApp(string id, string name, CdpChannel cha
3943

4044
return _registration[id].Factory(channel);
4145
}
46+
47+
internal static bool TryGetAppFactory(string id, string name, [MaybeNullWhen(false)] out CdpAppFactory<CdpAppBase> factory)
48+
{
49+
ArgumentException.ThrowIfNullOrEmpty(id);
50+
ArgumentException.ThrowIfNullOrEmpty(name);
51+
52+
if (!_registration.TryGetValue(id, out var appId))
53+
{
54+
factory = null;
55+
return false;
56+
}
57+
58+
factory = appId.Factory;
59+
return true;
60+
}
61+
}
62+
63+
public interface ICdpAppFactory<out TApp>
64+
where TApp : CdpAppBase
65+
{
66+
static abstract TApp Create(CdpChannel channel);
4267
}

‎lib/ShortDev.Microsoft.ConnectedDevices/CdpChannel.cs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,17 @@ void IDisposable.Dispose()
7474

7575
public void Dispose(bool closeSession = false, bool closeSocket = false)
7676
{
77+
MessageReceived = null;
78+
7779
_handler.UnregisterChannel(this);
7880
if (closeSocket)
7981
Socket.Dispose(); // ToDo: Heartbeat!
8082
if (closeSession)
8183
Session.Dispose(); // ToDo: Heartbeat!
8284
}
8385

84-
internal static CdpChannel CreateServerChannel(ChannelHandler handler, CdpSocket socket, StartChannelRequest request, ulong channelId, out CdpAppBase app)
85-
{
86-
CdpChannel channel = new(handler, channelId, socket);
87-
app = CdpAppRegistration.InstantiateApp(request.Id, request.Name, channel);
88-
return channel;
89-
}
86+
internal static CdpChannel CreateServerChannel(ChannelHandler handler, CdpSocket socket, ulong channelId)
87+
=> new(handler, channelId, socket);
9088

9189
internal static CdpChannel CreateClientChannel(ChannelHandler handler, CdpSocket socket, StartChannelResponse response)
9290
=> new(handler, response.ChannelId, socket);

‎lib/ShortDev.Microsoft.ConnectedDevices/CdpSession.cs‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,19 @@ void HandleSession(CommonHeader header, ref HeapEndianReader reader)
207207
}
208208
#endregion
209209

210-
public Task<CdpChannel> StartClientChannelAsync<TApp>(CancellationToken cancellationToken = default) where TApp : ICdpAppId
211-
=> StartClientChannelAsync(TApp.Id, TApp.Name, cancellationToken);
210+
public async Task<TApp> StartClientChannelAsync<TApp>(CancellationToken cancellationToken = default)
211+
where TApp : CdpAppBase, ICdpAppFactory<TApp>, ICdpAppId
212+
{
213+
var channel = await StartClientChannelAsync(TApp.Id, TApp.Name, cancellationToken).ConfigureAwait(false);
214+
return TApp.Create(channel);
215+
}
216+
217+
public async Task<TApp> StartClientChannelAsync<TApp>(string appId, string appName, CancellationToken cancellationToken = default)
218+
where TApp : CdpAppBase, ICdpAppFactory<TApp>
219+
{
220+
var channel = await StartClientChannelAsync(appId, appName, cancellationToken).ConfigureAwait(false);
221+
return TApp.Create(channel);
222+
}
212223

213224
public async Task<CdpChannel> StartClientChannelAsync(string appId, string appName, CancellationToken cancellationToken = default)
214225
{

‎lib/ShortDev.Microsoft.ConnectedDevices/Session/Channels/HostChannelHandler.cs‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,20 @@ protected override void HandleMessageInternal(CdpSocket socket, CommonHeader hea
2020
new byte[] { 0x30, 0x0, 0x0, 0x1 }
2121
));
2222
header.RequestID = 0;
23+
header.Flags = 0;
2324

24-
_channelRegistry.Create(channelId => CdpChannel.CreateServerChannel(this, socket, request, channelId, out _), out var channelId);
25+
(ChannelResult result, ulong channelId) result;
26+
if (!CdpAppRegistration.TryGetAppFactory(request.Id, request.Name, out var appFactory))
27+
{
28+
result = (ChannelResult.Failure_NotFound, 0);
29+
}
30+
else
31+
{
32+
var channel = _channelRegistry.Create(channelId => CdpChannel.CreateServerChannel(this, socket, channelId), out var channelId);
33+
appFactory(channel);
34+
result = (ChannelResult.Success, channelId);
35+
}
2536

26-
header.Flags = 0;
2737
Session.SendMessage(
2838
socket,
2939
ref header,
@@ -33,8 +43,8 @@ protected override void HandleMessageInternal(CdpSocket socket, CommonHeader hea
3343
},
3444
new StartChannelResponse()
3545
{
36-
Result = ChannelResult.Success,
37-
ChannelId = channelId
46+
Result = result.result,
47+
ChannelId = result.channelId
3848
}
3949
);
4050
}

0 commit comments

Comments
 (0)