Bilal Harb
Bilal Harb

Reputation: 29

Concurrent users to a windows form application

I am developing a client-server based application. And I want to limit the number of users logging in to my application . My first approach was create a table (call it "X") to store the userid,machine name , IP .. of every user that successfully logins to the app. At each login , I check the number of rows in table "X", if equals to the limit then I alert the user , if not I add a new record to table "X" , store the current row as an object in a static object. When the user logs out , I delete the record associated with the saved static object. I am calling the function that deletes the record in the formclosing event and this is working fine but the only issue is that if I press on "End Task" or "End process" or any other abnormal action , the record remains in the table. What do you suggest to do in this case ?

Upvotes: 1

Views: 909

Answers (3)

Bilal Harb
Bilal Harb

Reputation: 29

Thank you guys for the suggestions. After discussing the issue further with the team , I decided to run a tiny background app when the user logins, passing the right parameters and this app will do all the checks for me.

Upvotes: 0

silver
silver

Reputation: 1703

I had a similar dilemma and I've decided to keep everything in the cache/DB forever. my solution was that I'm limiting the cache size... (you can find my code below)

public class CacheWithSizeLimit<TKey,TValue>
{
    private int _cacheSize;

    public CacheWithSizeLimit(int cacheSize = 10000)
    {
        Cache = new ConcurrentDictionary<int, KeyValuePair<TKey, TValue>>();
        _cacheSize = cacheSize;
    }

    private ConcurrentDictionary<int, KeyValuePair<TKey, TValue>> Cache { get; set; }

    public TValue GetCachedValue(TKey inputKey)
    {
        KeyValuePair<TKey,TValue> result;
        var key = inputKey.GetHashCode() % _cacheSize;

        Cache.TryGetValue(key, out result);

        if (!IsNullOrEmpty(result.Key) && result.Key.Equals(inputKey))
        {
            return result.Value;
        }
        return default(TValue);
    }

    private bool IsNullOrEmpty<T>(T value)
    {
        return EqualityComparer<T>.Default.Equals(value, default(T));
    }

    public void SetCachedValue(TKey inputKey, TValue inputValue)
    {
        var key = inputKey.GetHashCode() % _cacheSize;
        Cache.AddOrUpdate(key, new KeyValuePair<TKey, TValue>(inputKey, inputValue));
    }

    internal void Clear()
    {
            Cache = new ConcurrentDictionary<int, KeyValuePair<TKey, TValue>>();
    }
}

if this approach doesn't work for you then you can rely on the actual connection disconnection event or a timeout.

Upvotes: 0

Andrey Polyakov
Andrey Polyakov

Reputation: 233

The best way is to create long-life tcp connection to your server and detect when it's closing -- it will happen in any reason from app termination to network fails.

If your server technology doesn't allow to create such connection. You should periodicaly send "I'm alive" packets from client to server. And if some timeout exceeded, mark such client as disconnected.

Upvotes: 1

Related Questions