Firebird Vt ile hazırladığım projede kullanıcı bilgilerinin(ad, şifre ve yetkileri) tutuduğu bi tablom var.
Programın ilk açılışında kullnıcı adı ve şifresini alarak bu tabloda sorgulama yaptırırark programa girişine izin veriyorum.
Ancak A terminalinden giriş yapmış olan bi kullanıcı aynı anda B termianlinden de giriş yapabiliyor. Bunu engellemenin yolu nasıl olmalıdır.
Ben kullanıcı tablosuna eklemeyi düşündüğüm bir boolean tipi alanı, kullnıcı giriş yaptığında TRUE yaparak, oturumu kapattığında ise FALSE yaparak bu kontrolü yapmayı düşünüyorum ancak kullanıcı giriş yaptığı bi esnada (alan TRUE) iken program kilitlenir veya elektrik kesintisi olursa bu durumda alan TRUE olarak kalacağı için ilgili kullanıcı bir daha hiç giriş yapamayacaktır.
Bu konuda fikri olan yada bunu uygulayabilen arkadaşlar var mı ?
bir login ekranı olduğunu dusunelim ve kullanıcı şifresini girip tamam düğmesine bastı...
Kod: Tümünü seç
// kullanıcı adı ve şifre gerekli dosyadan kontrol edilecek hata varsa mesaj verilecek yoksa aşağıdaki kod çalışacak. // kullanıcının adı ve şifresinin yazılı olduğu dosyada kullanıcının RecNo su tekdir. (burdaki RecNo paradox daki Recno dur. Firebird deki kullanıcıları tuttuğunuz dosyada bir sıra no su varsa bunu kullanabilirsiniz. Yoksa kullanıcı adı iki tane olamayacağı için kullanıcı adını kullanabilirsiniz) // dosya adı birbirinin aynısı olmasın. Örneğin kullanıcı, kullanıcıların tutulduğu dosyada 4. sıradaysa; // dosya adı 4Tmp.bin şeklinde olacak... 8. sıradaysa dosya adı 8Tmp.bin şeklinde olacak. // (ben dosya isimlerinin aynı olmaması için bu yöntemi kullandım, kullanıcı adı da kullanılabilir ) FileName = ExtractFilePath(Application->ExeName); FileName = FileName + IntToStr(User->RecNo) + "Tmp.bin"; // login ekranında kullanıcının adını girdiği textbox ın ( UserUSERNAME->Text ) içeriği (kullanıcı adını adını al) char *a[] = { UserUSERNAME->Text.c_str() }; // eger dosya varsa... if (FileExists(FileName)) { // dosyayı aç. FileHandle = FileOpen(FileName, fmOpenRead); // eger dosya açılamıyorsa... if( FileHandle == -1 ) { ShowMessage("Ayni İsimde İki Kullanıcı Baglanamaz"); Edit1->SelectAll(); Edit1->SetFocus(); return; } else { //dosya bir sekilde oluşturulmus ve exe nin olduğu dizinde kalmış. (anormal kapanmalar, program kilitlenmeleri v.s.) // dosya kapat. tekrar oluştur ve kullanıcı adını dosyaya yaz. FileClose(FileHandle); FileHandle = FileCreate(FileName); FileWrite(FileHandle, (char*)&a, sizeof(char *) ); } } // dosya yoksa, dosyayı oluştur, kullanıcı adını yaz. else { FileHandle = FileCreate(FileName); FileWrite(FileHandle, (char*)&a, sizeof(char *) ); }
burda dosyaya kullanıcı adı yazıldıktan sonra dosya açık bırakılıyor. bu durumda dosya kullanıldığından dosyaya başka bir işlem yapılamıyor.
(hem işletim sistemi tarafından hem programın kendisi tarafından.)
program ilk çalıştırıldığında dosyayı oluşturup içine kullanıcı adını yazıyor ve dosyayı açık bırakıyor. ikinci kez çalıştırıldığında önceki çalışmadan dosya açık olduğundan dosyayı açamıyor ve hata veriyor. bu durumda program daha önceden çalıştırılmış demektir. (aynı kullanıcı iki kere giremez)
Not : eger program local çalışıyorsa ve makina anormal kapandıysa, tekrar açıldığında .bin dosyasına bozuluyor ve checkdisk yapıyor.
umarım işinize yarar.
Konuş da feyiz alsınlar
Bilmiyorsan tut dilini
Seni bir adam sansınlar
Tek çözüm TimeOut mantığını kullanmak gibi geliyor. Öncelikle User tablonda zaman bilgisini takip edebileceğin bir field eklemen gerekir. Kullanıcılardan herhangi birisi login olunca zamanı bu filed'e yazar ve 10 sn'yede bir de zamanı yeniler.
Aynı user bilgisi ile başka bir terminal login olmak isterse zaman field'i ile o anki zaman arasında 10 saniyeden fazla bir süre varsa ilk kullanıcının TimeOut olduğu varsayılır ve login diğer terminal için başarılı olur. Aksi durumda diğer terminal için login başarısız olur.
Bu konuda hiç uğraşmadım ancak mesjınızı okuduğumda aklıma şöyle bir fikir geldi kullanıcı durumunu false turu olarak tutuyorsunuz. Kullanıcı vt ye login olmak istediğinde duruma baksın durum true ise yani kullanıcı açık gözüküyorsa durumu false yapsın bu arada bir triger ile durumu takip edelim ve durum true den false dönüştürüldüğünde bağlı olan terminallere vt den mesaj gönderilsin bağlı terminaller mesajı aldığında kullanıcı adlarına bağlı olarak durumlarını true olarak doğrulasın böylece bağlantı yapmak isteyen kullanıcı başka bir terminalde oturum açtı ise durum tekrar true olacaktır. Mesajlaşma için ortalama bir süre bırakılarak durum tekrar kontrol edilsin eğer durum da bir değişiklik olmadı ise hala false ise durumu true yaparak oturumu açmasına izin versin yok durum true olmuş ise başka bir terminalde oturumun açık olduğu belli olur ve kullanıcının oturum açması engellenir.
İlgelenen arkadaşlar için kısaca belirteyim
Kullanıcı bilgilerinin bulunduğu tabloya Time tipinde bir alan ekledim
ve aşağıdaki stroted procedure ile bu alana o anki saat bilsini update ettim
Kod: Tümünü seç
BEGIN UPDATE KULLANICILAR SET SAAT=CURRENT_TIME WHERE KULLANICIID=:PKULLANICI; SUSPEND; END
ve program giriş kısmında da aşağıdaki başka bir stroted procedure ile kullanıcının oturum açıkken update edilen son saat bilgisi ile o anki saat bilgisini karşılaştırotum aradaki fark 10 den fazla ile OffLine, değilse OnLine olduğunu geri döndüyorum geri dönen değeri Delphi içinde kontrol ettirerek kullnıcının bağlı olup olmadığını anlıyorum
Kod: Tümünü seç
SELECT SAAT FROM KULLANICILAR WHERE KULLANICIID=:PKULLANICIID INTO PSAAT; PSUAN=CURRENT_TIME; IF ((PSUAN-PSAAT)<=10) THEN BEGIN ONLINE=1; /* ONLINE */ END ELSE BEGIN ONLINE=0; /* OFFLINE */ END