Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add main logic for Client Invocation #1687

Merged
merged 42 commits into from
Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
79a0567
main logic for client invocation
xingsy97 Sep 23, 2022
f3281af
add ClientInvocation main logic
xingsy97 Sep 23, 2022
790b6c0
bug fix
xingsy97 Sep 23, 2022
f594136
bug fix
xingsy97 Sep 23, 2022
9dccae7
bug fix
xingsy97 Sep 23, 2022
a7c8c8a
update
xingsy97 Sep 23, 2022
f1b96c1
update
xingsy97 Sep 23, 2022
b129204
update
xingsy97 Sep 26, 2022
f4e143c
sync with PR 1684 and some updates
xingsy97 Sep 27, 2022
ee60530
minor fix
xingsy97 Sep 27, 2022
d2a3178
update about nameProvider
xingsy97 Sep 27, 2022
8299c2d
Merge branch 'dev' into ci-main
xingsy97 Sep 28, 2022
d18743a
tmp
xingsy97 Sep 28, 2022
ecf28b4
update
xingsy97 Oct 10, 2022
789427d
Merge branch 'dev' into ci-main
xingsy97 Oct 10, 2022
a64dec1
solve conflict
xingsy97 Oct 14, 2022
9a57478
Merge branch 'dev' into ci-main
xingsy97 Oct 14, 2022
c8198d5
update
xingsy97 Oct 14, 2022
1ad6573
Merge branch 'dev' into ci-main
xingsy97 Oct 14, 2022
9265187
update
xingsy97 Oct 14, 2022
b93a8c1
minior fix
xingsy97 Oct 14, 2022
ec252ad
new-line character fix
xingsy97 Oct 14, 2022
886b985
minor fix
xingsy97 Oct 14, 2022
0c40d03
update
xingsy97 Oct 17, 2022
c337cd3
add new UTs and move existing UTs
xingsy97 Oct 20, 2022
3ba27a2
add & update UTs
xingsy97 Oct 20, 2022
4b1dc1e
Merge branch 'dev' into ci-main
xingsy97 Oct 20, 2022
fcb849e
migrate to ServiceConnection and ServiceLifetimeManager from their ba…
xingsy97 Oct 21, 2022
995cadb
Merge branch 'ci-main' of https://github.com/xingsy97/azure-signalr i…
xingsy97 Oct 21, 2022
d0a36d0
minor bug fix
xingsy97 Oct 21, 2022
fb5a38e
format clean
xingsy97 Oct 21, 2022
2d98f5a
bug fix for PingMessage
xingsy97 Oct 21, 2022
2c58f3b
bug fix & add log
xingsy97 Oct 21, 2022
e6dcc32
code clean
xingsy97 Oct 21, 2022
2168535
add RemoveInvocation for caller, improve exception handling
xingsy97 Oct 24, 2022
8a5356f
remove instanceId for caller AddInvocation
xingsy97 Oct 24, 2022
85f4b9f
make RemoveInvocation return void
xingsy97 Oct 24, 2022
67ff88c
update
xingsy97 Oct 24, 2022
51b1271
Merge branch 'dev' into ci-main
xingsy97 Oct 24, 2022
0e6631f
update
xingsy97 Oct 24, 2022
a80e79f
Merge branch 'ci-main' of https://github.com/xingsy97/azure-signalr i…
xingsy97 Oct 24, 2022
a1a38e2
minor fix
xingsy97 Oct 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<MicrosoftAspNetCoreHttpConnectionsClientPackage3_0Version>3.0.0</MicrosoftAspNetCoreHttpConnectionsClientPackage3_0Version>
<MicrosoftAspNetCoreHttpConnectionsClientPackage3_1Version>3.1.9</MicrosoftAspNetCoreHttpConnectionsClientPackage3_1Version>
<MicrosoftAspNetCoreHttpConnectionsClientPackage5_0Version>5.0.1</MicrosoftAspNetCoreHttpConnectionsClientPackage5_0Version>
<MicrosoftAspNetCoreHttpConnectionsClientPackage7_0Version>7.0.0-preview.7.22376.6</MicrosoftAspNetCoreHttpConnectionsClientPackage7_0Version>
<MicrosoftAspNetCoreHttpConnectionsCommonPackageVersion>1.0.4</MicrosoftAspNetCoreHttpConnectionsCommonPackageVersion>
<MicrosoftAspNetCoreHttpConnectionsCommonPackage3_0Version>3.0.0</MicrosoftAspNetCoreHttpConnectionsCommonPackage3_0Version>
<MicrosoftAspNetCoreHttpConnectionsCommonPackage3_1Version>3.1.9</MicrosoftAspNetCoreHttpConnectionsCommonPackage3_1Version>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.AspNetCore.SignalR;

namespace Microsoft.Azure.SignalR
{
internal class ClientInvocationManager
{
public IClientResultsManager Caller => _clientResultsManager;
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
public IRoutedClientResultsManager Router => _routedClientResultsManager;

private readonly IClientResultsManager _clientResultsManager;
private readonly IRoutedClientResultsManager _routedClientResultsManager;

public ClientInvocationManager(IHubProtocolResolver hubProtocolResolver)
{
_clientResultsManager = new ClientResultsManager(hubProtocolResolver);
_routedClientResultsManager = new RoutedClientResultsManager();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Buffers;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Azure.SignalR.Protocol;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Protocol;

namespace Microsoft.Azure.SignalR
{
internal class ClientResultsManager : IClientResultsManager, IInvocationBinder
{
public ClientResultsManager(IHubProtocolResolver hubProtocolResolver)
{
throw new NotImplementedException();
}

public string GetNewInvocationId(string connectionId, string serverGUID)
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
{
throw new NotImplementedException();
}

public Task<T> AddInvocation<T>(string connectionId, string invocationId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

public void AddServiceMappingMessage(string invocationId, ServiceMappingMessage serviceMappingMessage)
{
throw new NotImplementedException();
}

public bool TryRemoveInvocation(string invocationId, out PendingInvocation invocation)
{
throw new NotImplementedException();
}

public bool TryCompleteResult(string connectionId, CompletionMessage message)
{
throw new NotImplementedException();
}

public bool TryCompleteResultFromSerializedMessage(string connectionId, string protocol, ReadOnlySequence<byte> message)
{
throw new NotImplementedException();
}

// Implemented for interface `IInvocationBinder`
public Type GetReturnType(string invocationId)
{
throw new NotImplementedException();
}

public bool TryGetInvocationReturnType(string invocationId, out Type type)
{
throw new NotImplementedException();
}

public void CleanupInvocations(string instanceId)
{
throw new NotImplementedException();
}

// Unused, here to honor the IInvocationBinder interface but should never be called
public IReadOnlyList<Type> GetParameterTypes(string methodName) => throw new NotImplementedException();

// Unused, here to honor the IInvocationBinder interface but should never be called
public Type GetStreamItemType(string streamId) => throw new NotImplementedException();
#pragma warning restore IDE0060 // Remove unused parameter
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Buffers;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.SignalR.Protocol;
using Microsoft.AspNetCore.SignalR.Protocol;

namespace Microsoft.Azure.SignalR
{
internal interface IClientResultsManager
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
{
string GetNewInvocationId(string connectionId, string serverGUID);

Task<T> AddInvocation<T>(string connectionId, string invocationId, CancellationToken cancellationToken);

void AddServiceMappingMessage(string invocationId, ServiceMappingMessage serviceMappingMessage);

bool TryRemoveInvocation(string invocationId, out PendingInvocation invocation);

bool TryCompleteResult(string connectionId, CompletionMessage message);

/// <summary>
/// Try complete from <paramref name="message"/> which is serialized from a <see cref="CompletionMessage"/> in <paramref name="protocol"/>
/// </summary>
/// <param name="connectionId"></param>
/// <param name="protocol">Serialization protocol of <paramref name="message"/></param>
/// <param name="message">the seriazliation result of a <see cref="CompletionMessage"/></param>
/// <returns></returns>
bool TryCompleteResultFromSerializedMessage(string connectionId, string protocol, ReadOnlySequence<byte> message);
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved

bool TryGetInvocationReturnType(string invocationId, out Type type);

void CleanupInvocations(string instanceId);
}

internal record PendingInvocation(Type Type, string ConnectionId, object Tcs, Action<object, CompletionMessage> Complete)
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Protocol;

namespace Microsoft.Azure.SignalR
{
internal interface IRoutedClientResultsManager
{
Task<object> AddRoutedInvocation(string connectionId, string invocationId, string callerServerId, CancellationToken cancellationToken);

bool TryCompleteResult(string connectionId, CompletionMessage message);

bool TryGetRoutedInvocation(string invocationId, out RoutedInvocation routedInvocation);

bool TryGetInvocationReturnType(string invocationId, out Type type);

void CleanupInvocations(string instanceId);
}

internal record RoutedInvocation(string ConnectionId, string CallerServerId, object Tcs, Action<object, CompletionMessage> Complete)
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Protocol;

namespace Microsoft.Azure.SignalR
{
internal class RoutedClientResultsManager : IRoutedClientResultsManager
{
public Task<object> AddRoutedInvocation(string connectionId, string invocationId, string callerServerId, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

public bool TryCompleteResult(string connectionId, CompletionMessage message)
{
throw new NotImplementedException();
}

public bool TryGetRoutedInvocation(string invocationId, out RoutedInvocation routedInvocation)
{
throw new NotImplementedException();
}

public bool TryGetInvocationReturnType(string invocationId, out Type type)
{
throw new NotImplementedException();
}

public void CleanupInvocations(string instanceId)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,33 @@
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0</TargetFrameworks>
<TargetFrameworks>netstandard2.0;netcoreapp3.0;net5.0;net7.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Microsoft.Azure.SignalR.Protocols\Microsoft.Azure.SignalR.Protocols.csproj" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net7.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Client" Version="$(MicrosoftAspNetCoreHttpConnectionsClientPackage7_0Version)" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Client" Version="$(MicrosoftAspNetCoreHttpConnectionsClientPackage5_0Version)" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Client" Version="$(MicrosoftAspNetCoreHttpConnectionsClientPackage3_0Version)" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="$(MicrosoftAspNetCoreSignalRPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections.Client" Version="$(MicrosoftAspNetCoreHttpConnectionsClientPackageVersion)" />
</ItemGroup>

<!-- New packages should be added to Directory.Build.props! -->
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ internal abstract class ServiceConnectionBase : IServiceConnection

private readonly IServiceEventHandler _serviceEventHandler;

private readonly ClientInvocationManager _clientInvocationManager;
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved

private readonly object _statusLock = new object();

private volatile string _errorMessage;
Expand Down Expand Up @@ -103,6 +105,7 @@ protected set

public Task ConnectionOfflineTask => _serviceConnectionOfflineTcs.Task;

// TODO: use DependencyInjection for ClientInvocationManager and then sort parameter order
protected ServiceConnectionBase(
IServiceProtocol serviceProtocol,
string serverId,
Expand All @@ -112,7 +115,8 @@ protected ServiceConnectionBase(
IServiceEventHandler serviceEventHandler,
ServiceConnectionType connectionType,
ILogger logger,
GracefulShutdownMode mode = GracefulShutdownMode.Off)
GracefulShutdownMode mode = GracefulShutdownMode.Off,
ClientInvocationManager clientInvocationManager = null)
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
{
ServiceProtocol = serviceProtocol;
ServerId = serverId;
Expand All @@ -132,6 +136,7 @@ protected ServiceConnectionBase(
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
_serviceMessageHandler = serviceMessageHandler;
_serviceEventHandler = serviceEventHandler;
_clientInvocationManager = clientInvocationManager;
}

/// <summary>
Expand Down Expand Up @@ -300,6 +305,9 @@ protected Task OnPingMessageAsync(PingMessage pingMessage)
if (RuntimeServicePingMessage.TryGetOffline(pingMessage, out var instanceId))
{
Log.ReceivedInstanceOfflinePing(Logger, instanceId);
#if NET7_0_OR_GREATER
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
_clientInvocationManager?.Caller.CleanupInvocations(instanceId);
#endif
return CleanupClientConnections(instanceId);
}
if (RuntimeServicePingMessage.IsFinAck(pingMessage))
Expand All @@ -310,6 +318,32 @@ protected Task OnPingMessageAsync(PingMessage pingMessage)
return _serviceMessageHandler.HandlePingAsync(pingMessage);
}

#if NET7_0_OR_GREATER
private Task OnClientInvocationAsync(ClientInvocationMessage message)
{
_clientInvocationManager.Router.AddRoutedInvocation(message.ConnectionId, message.InvocationId, message.CallerServerId, new CancellationToken());
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
return Task.CompletedTask;
}

private Task OnServiceMappingAsync(ServiceMappingMessage message)
{
_clientInvocationManager.Caller.AddServiceMappingMessage(message.InstanceId, message);
return Task.CompletedTask;
}

private Task OnClientCompletionAsync(ClientCompletionMessage clientCompletionMessage)
{
_clientInvocationManager.Caller.TryCompleteResultFromSerializedMessage
(clientCompletionMessage.ConnectionId, clientCompletionMessage.Protocol, clientCompletionMessage.Payload);
return Task.CompletedTask;
}

private Task OnErrorCompletionAsync(ErrorCompletionMessage errorCompletionMessage)
{
return Task.CompletedTask;
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
}
#endif

protected Task OnAckMessageAsync(AckMessage ackMessage)
{
_serviceMessageHandler.HandleAck(ackMessage);
Expand Down Expand Up @@ -562,6 +596,12 @@ private Task DispatchMessageAsync(ServiceMessage message)
AckMessage ackMessage => OnAckMessageAsync(ackMessage),
ServiceEventMessage eventMessage => OnEventMessageAsync(eventMessage),
AccessKeyResponseMessage keyMessage => OnAccessKeyMessageAsync(keyMessage),
#if NET7_0_OR_GREATER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to ifdef here?

ClientInvocationMessage clientInvocationMessage => OnClientInvocationAsync(clientInvocationMessage),
xingsy97 marked this conversation as resolved.
Show resolved Hide resolved
ServiceMappingMessage serviceMappingMessage => OnServiceMappingAsync(serviceMappingMessage),
ClientCompletionMessage clientCompletionMessage => OnClientCompletionAsync(clientCompletionMessage),
ErrorCompletionMessage errorCompletionMessage => OnErrorCompletionAsync(errorCompletionMessage),
#endif
_ => Task.CompletedTask,
};
}
Expand Down
Loading