I build a SPA with angular and hit the problem for message size in signalR, but before increasing and just moving the problem to later, I wanted to split the message with a stream.
it is pretty straight forward:
const subject = new Subject<any>();
try
{
await this.hubConn.send("Values", id, subject) // X
.catch(err => console.error(err));
for (let i = 0; i < values.length; ++i)
subject.next(values[i]);
subject.complete();
}
catch (err: any)
{
subject.error('Error');
console.error(err.message);
}
But I get an error in the line marked with // X
after some investigation I found that on the second iteration the streamId
is distinct
:
I build a small example to check what happens:
var streams = [];
streams[4] = {};
for (const streamId in streams)
console.debug(streamId);
which gives me this result:
4
distinct
equals
firstOrDefault
lastOrDefault
pushSorted
but that means that iterating over the keys always iterates over the array functions, but I found nothing regarding this problem...
I'm using:
angular 16.2
typescript 5.1.6
signalR 7.0.9 and 8.0.7 (tried both)
nodejs 16.20.2
and I have the target ES2022
so either no one ever tried streaming (which sounds way to unlikely), I have a version incompatibility or I have some mistake in my code which I can't see...
Does anyone has an idea why this might not work?
// Edit: Here the serverside method to receive the values:
[HubMethodName(nameof(Values))]
public async Task Values(string id, IAsyncEnumerable<object> values)
{
try
{
object[] result = null;
if (values != null)
result = await values.ToArrayAsync();
Debug.WriteLine(result);
}
catch (Exception ex)
{
SystemLogger.LogCritical("{ex}", ex);
}
}
It's very likely that you are using a library that modifies Array.prototype
in a wrong way:
Array.prototype.distinct = function() { return [...new Set(this)]; };
The correct way is to use Object.defineProperty
(or even better, not to change the core prototypes at all). In this case the property would not become enumerable.
Object.defineProperty(Array.prototype, 'distinct', {
value: function() { return [...new Set(this)]; }
});