Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Messages between users on Blazor using events creating errors

$
0
0

I have a Blazor Server app where users are able to send messages between users.

There is a service that tracks user circuits as they connect and disconnect (below)

public class UserCircuit{    public List<string> CircuitIds { get; set; }    public event Action<ProjectMessageDto> MessageReceived;    public void NotifyMessageReceived(ProjectMessageDto message) => MessageReceived?.Invoke(message);    public UserCircuit()    {        CircuitIds = new List<string>();    }}    public class TrackingCircuitHandler() : CircuitHandler    {        private static readonly ConcurrentDictionary<string, UserCircuit> connectedUsers = new();        public override async Task OnConnectionUpAsync(Circuit circuit, CancellationToken cancellationToken)        {            var userId = await GetStatUser();            if (userId != null)            {                lock (connectedUsers)                {                    connectedUsers.TryGetValue(userId, out var userCircuit);                    userCircuit ??= new UserCircuit();                    userCircuit.CircuitIds.Add(circuit.Id);                    connectedUsers.TryAdd(userId, userCircuit);                }            }        }          public override async Task OnConnectionDownAsync(Circuit circuit, CancellationToken cancellationToken)        {            var userId = await GetStatUser();            if (userId != null)            {                lock (connectedUsers)                {                    connectedUsers.TryGetValue(userId, out var userCircuit);                    userCircuit ??= new UserCircuit();                    userCircuit.CircuitIds.Remove(circuit.Id);                    connectedUsers.TryAdd(userId, userCircuit);                    if (userCircuit.CircuitIds.Count == 0)                    {                        connectedUsers.TryRemove(userId, out var garbage);                    }                }            }        }        public async Task<UserCircuit> GetUserCircuit()        {            var userId = await GetStatUser();            if (userId != null)            {                connectedUsers.TryGetValue(userId, out var userCircuit);                return userCircuit;            }            return null;        }        public async Task<string> GetStatUser()        {            return "userid123";        }        public void NotifyMessageReceived(List<string> userIds, ProjectMessageDto message)        {            foreach (var userId in userIds)            {                connectedUsers.TryGetValue(userId, out var userCircuit);                if (userCircuit != null)                {                    userCircuit.NotifyMessageReceived(message);                }            }        }    }

We then have user1 who sends a message to users:

_usersStateContainer.NotifyMessageReceived(notifyIds, messageDto);

And then user2 who is receiving the message:

protected override Task OnInitializedAsync(){    state.OnMessageReceived += StateOnOnMessageReceived;    return base.OnInitializedAsync();}private async void StateOnOnMessageReceived(ProjectMessageDto message){    // Handling the message    await InvokeAsync(StateHasChanged);}

This works. But if (for any reason) user2 throws an exception (can simulate it like below) This exception actually throws on user1's browser, and kills user1.

private async void StateOnOnMessageReceived(ProjectMessageDto message){    throw new Exception("DEAD");}

I understand(ish) the reasons for this occurring. But am I missing a trick here? User1 should be firing off the message and essentially forgetting about it (it doesn't need delivery or anything like that), it certainly shouldn't be dying if user2 throws. Is there a better way to be handling this?


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>