Από τη στιγμή που συζητάμε για το πως μπορούν να βρεθούν οι χρήστες που έχουν συνδεθεί στον SQL Server, είναι πάρα πολύ πιθανό η εφαρμογή να είναι desktop. Εξάλλου το είδος αυτό της ερώτησης είναι αρκετά συχνό. Οι άλλες πιθανόητες θα ήταν εφαρμογές windows services. Οι web εφαρμογές, εκ φύσεως, δεν κρατάνε ανοικτές συνδέσεις για πολύ ώρα, οπότε δεν μπορείς να βρεις τους συνδεδεμένους χρήστες από τη βάση.
Το κύριο πρόβλημα με τη χρήση ενός πίνακα συνδεδεμένω χρηστών στη βάση είναι ότι δεν αντιμετωπίζει εύκολα την περίπτωση της απότομης διακοπής της σύνδεσης. Σε αρκετές περιπτώσεις αρκεί περιοδικά να καθαρίζει κανείς τον πίνακα και να αφήσει τον administrator να αντιμετωπίσει τις περιπτώσεις που κάποιος χρήστης χάσει τη σύνδεση και δεν μπορεί να ξανασυνδεθεί μέχρι το επόμενο καθάρισμα του πίνακα. Σε κάποιες άλλες όμως αυτό δεν αρκεί. Το περιοδικό καθάρισμα του πίνακα δεν μπορεί να είναι πολύ συχνό (σε διάστημα δευτερολέπτων) λόγω κόστους της επικοινωνίας με τη βάση.
Η λύση του ελέγχου sys.dm_exec_sessions έχει το καλό ότι θέλει ελάχιστο κώδικα, αλλά δεν θα τα πάει καλά αν θέλει κάποιος να χρησιμοποιήσει connection pooling ή άλλες προχωρημένες αρχιτεκτονικές στις οποίες δεν αντιστοιχεί μία σύνδεση ανά χρήστη. Μία τέτοια περίπτωση θα είναι π.χ. να χρησιμοποιήσει MSMQ ή Queued Services.
Μία λύση η οποία χρησιμοποιείται από πολλές εφαρμογές για license management είναι η χρήση ενός server component το οποίο καλούν οι εφαρμογές όταν ξεκινάνε ή κλείνουν. Το component αυτό αναλαμβάνει να κρατήσει ποιοί χρήστες είναι συνδεδεμένοι κάθε στιγμή. Αν με κάποιο τρόπο διατηρείται ανοικτή η σύνδεση στο component για όλη τη ζωή της εφαρμογής, μπορεί κανείς να χειριστεί σχετικά αυτόματα και την απότομη απώλεια σύνδεσης. Πολύ απλά, όταν το component αντιληφθεί την απώλεια σύνδεσης διαγράφει την εγγραφή του αντίστοιχου χρήστη.
Ένας τρόπος να υλοποιήσει κανείς ένα τέτοιο license manager είναι να δημιουργήσει ένα per-session component στο WCF και να κρατήσει το reference στο component σε ένα global variable. Το ίδιο μπορεί να γίνει και με Enterprise Services και με Remoting.
Άλλη λύση είναι οι εφαρμογές να επικοινωνούν περιοδικά με τον license manager μέσω UDP packets και αυτός να τους απαντάει ότι μπορούν να συνεχίσουν να δουλεύουν. Αν ο license manager δεν λάβει απάντηση από ένα client για αρκετή ώρα, θεωρεί ότι δεν τρέχει πλέον. Ο manager θα πρέπει να απαντάει στους clients για να εμποδίσει κάποιος πονηρούς χρήστες να τον παρακάμψουν μπλοκάροντας τα απαραίτητα ports. Η επικοινωνία αυτή θα μπορεί να γίνει πολύ συχνά καθώς τα UDP πακέτα είναι πολύ μικρά και η επεξεργασία τους δεν θα κοστίζει ιδιαίτερα στο server - σε αντίθεση με τον έλεγχο των συνδέσεων στη βάση.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos