Skip to content

Commit ee79c28

Browse files
Mitch528galvesribeiro
authored andcommitted
Add support for handling multiple arguments (#14)
* Fix handle not being removed * Add support for handling multiple arguments
1 parent 779f92e commit ee79c28

File tree

6 files changed

+169
-16
lines changed

6 files changed

+169
-16
lines changed

src/Blazor.Extensions.SignalR.JS/src/HubConnectionManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export class HubConnectionManager {
6363

6464
public StartConnection = (connectionId: string): Promise<void> => {
6565
const connection = this.GetConnection(connectionId);
66-
66+
6767
return connection.start();
6868
}
6969

@@ -97,7 +97,7 @@ export class HubConnectionManager {
9797

9898
public On = (connectionId: string, callback: DotNetReferenceType) => {
9999
const connection = this.GetConnection(connectionId);
100-
const handle = (payload) => callback.invokeMethodAsync<void>('On', JSON.stringify(payload));
100+
const handle = (...payloads) => callback.invokeMethodAsync<void>('On', payloads.map(payload => JSON.stringify(payload)));
101101

102102
this._handles.set(callback.invokeMethod<string>('get_Id'), handle);
103103

src/Blazor.Extensions.SignalR/HubConnection.cs

Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,120 @@ public HubConnection(HttpConnectionOptions options)
3737
public Task StartAsync() => JSRuntime.Current.InvokeAsync<object>(START_CONNECTION_METHOD, this.InternalConnectionId);
3838
public Task StopAsync() => JSRuntime.Current.InvokeAsync<object>(STOP_CONNECTION_METHOD, this.InternalConnectionId);
3939

40-
public IDisposable On<TResult>(string methodName, Func<TResult, Task> handler)
40+
public IDisposable On<TResult1>(string methodName, Func<TResult1, Task> handler)
41+
=> On<TResult1, object, object, object, object, object, object, object, object, object>(methodName,
42+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1));
43+
44+
public IDisposable On<TResult1, TResult2>(string methodName, Func<TResult1, TResult2, Task> handler)
45+
=> On<TResult1, TResult2, object, object, object, object, object, object, object, object>(methodName,
46+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2));
47+
48+
public IDisposable On<TResult1, TResult2, TResult3>(string methodName, Func<TResult1, TResult2, TResult3, Task> handler)
49+
=> On<TResult1, TResult2, TResult3, object, object, object, object, object, object, object>(methodName,
50+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3));
51+
52+
public IDisposable On<TResult1, TResult2, TResult3, TResult4>(string methodName, Func<TResult1, TResult2, TResult3, TResult4, Task> handler)
53+
=> On<TResult1, TResult2, TResult3, TResult4, object, object, object, object, object, object>(methodName,
54+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4));
55+
56+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5>(string methodName, Func<TResult1, TResult2, TResult3, TResult4, TResult5, Task> handler)
57+
=> On<TResult1, TResult2, TResult3, TResult4, TResult5, object, object, object, object, object>(methodName,
58+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4, t5));
59+
60+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6>(string methodName,
61+
Func<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, Task> handler)
62+
=> On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, object, object, object, object>(methodName,
63+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4, t5, t6));
64+
65+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7>(string methodName,
66+
Func<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, Task> handler)
67+
=> On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, object, object, object>(methodName,
68+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4, t5, t6, t7));
69+
70+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8>(string methodName,
71+
Func<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, Task> handler)
72+
=> On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, object, object>(methodName,
73+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4, t5, t6, t7, t8));
74+
75+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9>(string methodName,
76+
Func<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9, Task> handler)
77+
=> On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9, object>(methodName,
78+
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) => handler(t1, t2, t3, t4, t5, t6, t7, t8, t9));
79+
80+
public IDisposable On<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9, TResult10>(string methodName,
81+
Func<TResult1, TResult2, TResult3, TResult4, TResult5, TResult6, TResult7, TResult8, TResult9, TResult10, Task> handler)
4182
{
4283
if (string.IsNullOrEmpty(methodName)) throw new ArgumentNullException(nameof(methodName));
4384
if (handler == null) throw new ArgumentNullException(nameof(handler));
4485

4586
var callbackId = Guid.NewGuid().ToString();
4687

4788
var callback = new HubMethodCallback(callbackId, methodName, this,
48-
(json) =>
89+
(payloads) =>
4990
{
50-
var payload = Json.Deserialize<TResult>(json);
51-
return handler(payload);
91+
TResult1 t1 = default;
92+
TResult2 t2 = default;
93+
TResult3 t3 = default;
94+
TResult4 t4 = default;
95+
TResult5 t5 = default;
96+
TResult6 t6 = default;
97+
TResult7 t7 = default;
98+
TResult8 t8 = default;
99+
TResult9 t9 = default;
100+
TResult10 t10 = default;
101+
102+
if (payloads.Length > 0)
103+
{
104+
t1 = Json.Deserialize<TResult1>(payloads[0]);
105+
}
106+
if (payloads.Length > 1)
107+
{
108+
t2 = Json.Deserialize<TResult2>(payloads[1]);
109+
}
110+
if (payloads.Length > 2)
111+
{
112+
t3 = Json.Deserialize<TResult3>(payloads[2]);
113+
}
114+
if (payloads.Length > 3)
115+
{
116+
t4 = Json.Deserialize<TResult4>(payloads[3]);
117+
}
118+
if (payloads.Length > 4)
119+
{
120+
t5 = Json.Deserialize<TResult5>(payloads[4]);
121+
}
122+
if (payloads.Length > 5)
123+
{
124+
t6 = Json.Deserialize<TResult6>(payloads[5]);
125+
}
126+
if (payloads.Length > 6)
127+
{
128+
t7 = Json.Deserialize<TResult7>(payloads[6]);
129+
}
130+
if (payloads.Length > 7)
131+
{
132+
t8 = Json.Deserialize<TResult8>(payloads[7]);
133+
}
134+
if (payloads.Length > 8)
135+
{
136+
t9 = Json.Deserialize<TResult9>(payloads[8]);
137+
}
138+
if (payloads.Length > 9)
139+
{
140+
t10 = Json.Deserialize<TResult10>(payloads[9]);
141+
}
142+
143+
return handler(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
52144
}
53145
);
54146

147+
RegisterHandle(methodName, callback);
148+
149+
return callback;
150+
}
151+
152+
internal void RegisterHandle(string methodName, HubMethodCallback callback)
153+
{
55154
if (this._callbacks.TryGetValue(methodName, out var methodHandlers))
56155
{
57156
methodHandlers[callback.Id] = callback;
@@ -65,9 +164,6 @@ public IDisposable On<TResult>(string methodName, Func<TResult, Task> handler)
65164
}
66165

67166
((IJSInProcessRuntime)JSRuntime.Current).Invoke<object>(ON_METHOD, this.InternalConnectionId, new DotNetObjectRef(callback));
68-
69-
//HubConnectionManager.On(this.InternalConnectionId, callback);
70-
return callback;
71167
}
72168

73169
internal void RemoveHandle(string methodName, string callbackId)
@@ -76,7 +172,7 @@ internal void RemoveHandle(string methodName, string callbackId)
76172
{
77173
if (callbacks.TryGetValue(callbackId, out var callback))
78174
{
79-
((IJSInProcessRuntime)JSRuntime.Current).Invoke<object>(OFF_METHOD, this.InternalConnectionId, new DotNetObjectRef(callback));
175+
((IJSInProcessRuntime)JSRuntime.Current).Invoke<object>(OFF_METHOD, this.InternalConnectionId, methodName, callbackId);
80176
//HubConnectionManager.Off(this.InternalConnectionId, handle.Item1);
81177
callbacks.Remove(callbackId);
82178

@@ -88,12 +184,13 @@ internal void RemoveHandle(string methodName, string callbackId)
88184
}
89185
}
90186

91-
public void OnClose(Func<Exception, Task> callback) {
187+
public void OnClose(Func<Exception, Task> callback)
188+
{
92189
this._closeCallback = new HubCloseCallback(callback);
93190
((IJSInProcessRuntime)JSRuntime.Current).Invoke<object>(ON_CLOSE_METHOD,
94191
this.InternalConnectionId,
95192
new DotNetObjectRef(this._closeCallback));
96-
}
193+
}
97194

98195
public Task InvokeAsync(string methodName, params object[] args) =>
99196
JSRuntime.Current.InvokeAsync<object>(INVOKE_ASYNC_METHOD, this.InternalConnectionId, methodName, args);

src/Blazor.Extensions.SignalR/HubMethodCallback.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ namespace Blazor.Extensions
77
public class HubMethodCallback : IDisposable
88
{
99
private readonly HubConnection _connection;
10-
private readonly Func<string, Task> _callback;
10+
private readonly Func<string[], Task> _callback;
1111

12-
public HubMethodCallback(string id, string methodName, HubConnection connection, Func<string, Task> callback)
12+
public HubMethodCallback(string id, string methodName, HubConnection connection, Func<string[], Task> callback)
1313
{
1414
this.MethodName = methodName;
1515
this.Id = id;
@@ -21,7 +21,7 @@ public HubMethodCallback(string id, string methodName, HubConnection connection,
2121
public string Id { [JSInvokable]get; private set; }
2222

2323
[JSInvokable]
24-
public Task On(string payload) => this._callback(payload);
24+
public Task On(string[] payloads) => this._callback(payloads);
2525

2626
public void Dispose()
2727
{

test/Blazor.Extensions.SignalR.Test.Client/Pages/Chat.cshtml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@
66
<form class="form-inline">
77
<div class="input-append">
88
<input type="button" class="btn" value="Gimme objects!" onclick=@TellHubToDoStuff />
9-
9+
10+
</div>
11+
</form>
12+
13+
<h4>Multiple Arguments</h4>
14+
<form class="form-inline">
15+
<div class="input-append">
16+
<input type="button" class="btn" value="Gimme multiple arguments!" onclick=@DoMultipleArgs />
17+
1018
</div>
1119
</form>
1220

test/Blazor.Extensions.SignalR.Test.Client/Pages/ChatComponent.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Net.Http;
7+
using System.Text;
78
using System.Threading.Tasks;
89

910
namespace Blazor.Extensions.SignalR.Test.Client.Pages
@@ -22,6 +23,8 @@ public class ChatComponent : BlazorComponent
2223

2324
private IDisposable _objectHandle;
2425
private IDisposable _listHandle;
26+
private IDisposable _multiArgsHandle;
27+
private IDisposable _multiArgsComplexHandle;
2528
private HubConnection _connection;
2629

2730
protected override async Task OnInitAsync()
@@ -70,6 +73,22 @@ public Task DemoMethodList(object data)
7073
return this.Handle(data);
7174
}
7275

76+
public Task DemoMultipleArgs(string arg1, int arg2, string arg3, int arg4)
77+
{
78+
this._logger.LogInformation("Got Multiple Args!");
79+
this._multiArgsHandle.Dispose();
80+
81+
return this.HandleArgs(arg1, arg2, arg3, arg4);
82+
}
83+
84+
public Task DemoMultipleArgsComplex(object arg1, object arg2)
85+
{
86+
this._logger.LogInformation("Got Multiple Args Complex!");
87+
this._multiArgsComplexHandle.Dispose();
88+
89+
return this.HandleArgs(arg1, arg2);
90+
}
91+
7392
private async Task<string> GetJwtToken(string userId)
7493
{
7594
var httpResponse = await this._http.GetAsync($"/generatetoken?user={userId}");
@@ -85,6 +104,16 @@ private Task Handle(object msg)
85104
return Task.CompletedTask;
86105
}
87106

107+
private Task HandleArgs(params object[] args)
108+
{
109+
string msg = string.Join(", ", args);
110+
111+
this._logger.LogInformation(msg);
112+
this._messages.Add(msg);
113+
this.StateHasChanged();
114+
return Task.CompletedTask;
115+
}
116+
88117
internal async Task Broadcast()
89118
{
90119
await this._connection.InvokeAsync("Send", this._toEverybody);
@@ -125,6 +154,14 @@ internal async Task LeaveGroup()
125154
await this._connection.InvokeAsync("LeaveGroup", this._groupName);
126155
}
127156

157+
internal async Task DoMultipleArgs()
158+
{
159+
this._multiArgsHandle = this._connection.On<string, int, string, int>("DemoMultiArgs", this.DemoMultipleArgs);
160+
this._multiArgsComplexHandle = this._connection.On<DemoData, DemoData[]>("DemoMultiArgs2", this.DemoMultipleArgsComplex);
161+
await this._connection.InvokeAsync("DoMultipleArgs");
162+
await this._connection.InvokeAsync("DoMultipleArgsComplex");
163+
}
164+
128165
internal async Task TellHubToDoStuff()
129166
{
130167
this._objectHandle = this._connection.On<DemoData>("DemoMethodObject", this.DemoMethodObject);

test/Blazor.Extensions.SignalR.Test.Server/Hubs/ChatHub.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ public override async Task OnDisconnectedAsync(Exception ex)
2727
await this.Clients.Others.SendAsync("Send", $"{this.Context.ConnectionId} left");
2828
}
2929

30+
public Task DoMultipleArgs()
31+
{
32+
return this.Clients.All.SendAsync("DemoMultiArgs", "one", 2, "three", 4);
33+
}
34+
35+
public Task DoMultipleArgsComplex()
36+
{
37+
return this.Clients.All.SendAsync("DemoMultiArgs2", new DemoData { Id = 1, Data = "Demo Data" },
38+
Enumerable.Range(1, 10).Select(x => new DemoData { Id = x, Data = $"Demo Data #{x}" }).ToList());
39+
}
40+
3041
public Task Send(string message)
3142
{
3243
return this.Clients.All.SendAsync("Send", $"{this.Context.ConnectionId}: {message}");

0 commit comments

Comments
 (0)