Base solution for your next web application
Open Closed

Track OnlineClient Connect/Disconnect in db table #5307


User avatar
0
JapNolt created

I want to track when certain clients (desktop clients) connect/disconnect from SignalR. I want to log each connect/disconnect in a database table. The question is specifically about writing to the database from inside an event. Can anybody think of a problem with doing it this way? Db contention, etc. Is there a preferred/better way?

using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.RealTime;
using MyProject.Timeline;

namespace MyProject.RealTimeCommand
{
    public class ClientStateWatcher : ISingletonDependency
    {
        private readonly IOnlineClientManager _onlineClientManager;
        private readonly IRepository<ClientStatus, long> _clientStatusRepository;

        public ClientStateWatcher(
                IOnlineClientManager onlineClientManager
                , IRepository<ClientStatus, long> clientStatusRepository
            )
        {
            _onlineClientManager = onlineClientManager;
            _clientStatusRepository = clientStatusRepository;
        }

        public void Initialize()
        {
            _onlineClientManager.ClientConnected += _onlineClientManager_ClientConnected;
            _onlineClientManager.ClientDisconnected += _onlineClientManager_ClientDisconnected;
        }

        private void _onlineClientManager_ClientConnected(object sender, OnlineClientEventArgs e)
        {
            TrackClientStatusChange(e.Client, true);
        }

        private void _onlineClientManager_ClientDisconnected(object sender, OnlineClientEventArgs e)
        {
            TrackClientStatusChange(e.Client, false);
        }

        private void TrackClientStatusChange(IOnlineClient onlineClient, bool connected)
        {
            if ((string)onlineClient.Properties.GetValueOrDefault(OccConsts.HttpHeader_ClientType) == "DesktopClient")
            {
            _clientStatusRepository.Insert(
                new ClientStatus
                {
                    Status = connected ? ConnectionState.ConnectedOrSignedIn : ConnectionState.DisconnectedOrSignedOut,
                    CreatorUserId = onlineClient.UserId,
                    TenantId = onlineClient.TenantId.Value
                });
            }
        }
    }
}

1 Answer(s)
  • User Avatar
    0
    alper created
    Support Team

    Hi,

    you can create a new scope for your database insert operation

    using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.RequiresNew))
    {
        //use repositories here. they will use a different (new) dbcontext
    
        uow.Complete();
    }