tgstation-server 6.12.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
HubConnectionExtensions.cs
Go to the documentation of this file.
1using System;
2using System.Linq;
3using System.Threading;
4using System.Threading.Tasks;
5
6using Microsoft.AspNetCore.SignalR.Client;
7
9{
14 {
21 public static void ProxyOn<TClientProxy>(this HubConnection hubConnection, TClientProxy proxy)
22 where TClientProxy : class
23 {
24 if (hubConnection == null)
25 throw new ArgumentNullException(nameof(hubConnection));
26
27 if (proxy == null)
28 throw new ArgumentNullException(nameof(proxy));
29
30 ProxyOn(hubConnection, typeof(TClientProxy), proxy);
31 }
32
39 static void ProxyOn(this HubConnection hubConnection, Type proxyType, object proxyObject)
40 {
41 var clientMethods = proxyType.GetMethods();
42 var cancellationTokenType = typeof(CancellationToken);
43 foreach (var clientMethod in clientMethods)
44 {
45 var parametersList = clientMethod
46 .GetParameters()
47 .Select(parameterInfo => parameterInfo.ParameterType)
48 .ToList();
49
50 var cancellationTokenIndex = parametersList.IndexOf(cancellationTokenType);
51 if (cancellationTokenIndex != -1)
52 {
53 parametersList.RemoveAt(cancellationTokenIndex);
54#if DEBUG
55 if (parametersList.IndexOf(cancellationTokenType) != -1)
56 throw new InvalidOperationException("Cannot ProxyOn a method with multiple CancellationToken parameters!");
57#endif
58 }
59
60 var parameters = parametersList.ToArray();
61
62 object?[] AddCancellationTokenToParametersArray(object?[] parametersArray)
63 {
64 if (cancellationTokenIndex == -1)
65 return parametersArray;
66
67 var newList = parametersArray.ToList();
68 newList.Insert(cancellationTokenIndex, CancellationToken.None);
69 return newList.ToArray();
70 }
71
72 var returnType = clientMethod.ReturnType;
73 if (returnType != typeof(Task))
74 {
75 if (returnType.BaseType != typeof(Task))
76 throw new InvalidOperationException($"Return type {returnType} of {proxyType.FullName}.{clientMethod.Name} is not supported! Only Task and derivatives are supported.");
77
78 var resultProperty = returnType.GetProperty(nameof(Task<object>.Result));
79 hubConnection.On(
80 clientMethod.Name,
81 parameters,
82 async (parameterArray, _) =>
83 {
84 var task = (Task)clientMethod.Invoke(proxyObject, AddCancellationTokenToParametersArray(parameterArray));
85 await task;
86 return resultProperty.GetValue(task);
87 },
88 hubConnection);
89 }
90 else
91 hubConnection.On(
92 clientMethod.Name,
93 parameters,
94 (parameterArray) =>
95 {
96 return (Task)clientMethod.Invoke(proxyObject, AddCancellationTokenToParametersArray(parameterArray));
97 });
98 }
99
100 foreach (var inheritedInterface in proxyType.GetInterfaces())
101 ProxyOn(hubConnection, inheritedInterface, proxyObject);
102 }
103 }
104}
static void ProxyOn(this HubConnection hubConnection, Type proxyType, object proxyObject)
Apply a given proxyObject to a given hubConnection .
static void ProxyOn< TClientProxy >(this HubConnection hubConnection, TClientProxy proxy)
Apply a given proxy to a given hubConnection .