C
C#2y ago
Thinker

❔ Best way to display a continually updating list of messages

@inject MerpieClient Client
@inject MerpieHubConnection HubConnection
@inject ILogger<MessageList> Logger

<div class="flex flex-col-reverse gap-y-4">
@foreach (var message in messages)
{
<MessageDisplay Message="message"/>
}
</div>

@code {

private readonly List<MessageDto> messages = new();

protected override async Task OnInitializedAsync()
{
await HubConnection.StartConnection();

HubConnection.OnMessageSent += OnMessageSent;
HubConnection.OnMessageDeleted += OnMessageDeleted;
HubConnection.OnMessageEdited += OnMessageEdited;

// Fetch messages
if (await Client.GetMessages() is ApiResult<IEnumerable<MessageDto>>.Success success)
messages.AddRange(success.Value);
}

private void OnMessageSent(MessageDto message)
{
Logger.LogInformation("Message with ID {id} received", message.Id);

messages.Insert(0, message);
StateHasChanged();
}

private void OnMessageDeleted(MessageDto message)
{
Logger.LogInformation("Message with ID {id} deleted", message.Id);

messages.Remove(message);
StateHasChanged();
}

private void OnMessageEdited(MessageDto oldMessage, MessageDto newMessage)
{
Logger.LogInformation("Message with ID {id} edited", oldMessage.Id);

messages[messages.IndexOf(oldMessage)] = newMessage;
StateHasChanged();
}

}
@inject MerpieClient Client
@inject MerpieHubConnection HubConnection
@inject ILogger<MessageList> Logger

<div class="flex flex-col-reverse gap-y-4">
@foreach (var message in messages)
{
<MessageDisplay Message="message"/>
}
</div>

@code {

private readonly List<MessageDto> messages = new();

protected override async Task OnInitializedAsync()
{
await HubConnection.StartConnection();

HubConnection.OnMessageSent += OnMessageSent;
HubConnection.OnMessageDeleted += OnMessageDeleted;
HubConnection.OnMessageEdited += OnMessageEdited;

// Fetch messages
if (await Client.GetMessages() is ApiResult<IEnumerable<MessageDto>>.Success success)
messages.AddRange(success.Value);
}

private void OnMessageSent(MessageDto message)
{
Logger.LogInformation("Message with ID {id} received", message.Id);

messages.Insert(0, message);
StateHasChanged();
}

private void OnMessageDeleted(MessageDto message)
{
Logger.LogInformation("Message with ID {id} deleted", message.Id);

messages.Remove(message);
StateHasChanged();
}

private void OnMessageEdited(MessageDto oldMessage, MessageDto newMessage)
{
Logger.LogInformation("Message with ID {id} edited", oldMessage.Id);

messages[messages.IndexOf(oldMessage)] = newMessage;
StateHasChanged();
}

}
This is a component in a Blazor WASM chat app I'm developing which job is to display a list of messages. However I'm wondering whether this is an alright-ish way to go about keeping a continually updating list of messages, because to me it feels a bit iffy. Especially the fact I have this Remove call which has to iterate through all the messages to remove it. I don't know how well this would scale or whether there is a better approach.
17 Replies
Kouhai
Kouhai2y ago
I have never touched blazor WASM, but Ideally you'd want to track the messages by their IDs
Thinker
ThinkerOP2y ago
That makes sense
Dusty
Dusty2y ago
I have something for a console history. Because of that I don't have the removal part. With 5k lines it still works without freezing. I haven't tested more. You could use a HashSet but iterating would be slower then. So I guess your impl is good
Thinker
ThinkerOP2y ago
Thing is that this needs to be ordered And hash sets have no order
Dusty
Dusty2y ago
Oh yea makes sense obviously I guess you could try to return thousands of msgs and remove random ones to see how it behaves
Kouhai
Kouhai2y ago
you can keep your list sorted by message id that way you dont have to traverse the full list
Thinker
ThinkerOP2y ago
That'd be better I suppose I could do a binary search thing, either by ID or by message creation date
Kouhai
Kouhai2y ago
yeah you could also go for a twitter/discord snowflake approach for the timestamp and id
Thinker
ThinkerOP2y ago
hmm, I haven't investigated how that works. Got any resources for it?
Kouhai
Kouhai2y ago
@🌈 Thinker 🌈 Just a note whether you need need a snowflake or not depends on many factors, because it's usually used for distributed systems, but the general idea might help you nonetheless https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake This was the official announcement from Twitter https://github.com/aevitas/flakeid/blob/master/src/FlakeId/Id.cs And here is an C# implementation of snowflake I found on github This is also how discord encodes it
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Thinker
ThinkerOP2y ago
My messages already have a timestamp so I don't think it's necessary to encode that in the ID
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Thinker
ThinkerOP2y ago
I only have a single server so that's probably not an issue
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.

Did you find this page helpful?