Bağlantıyı dışarıdan almak

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

Merhabalar herkese.

3 adet uygulamam var.

a. Ana uygulama
1. Yan Uygulama
2. Yan Uygulama

Ana uygulamada adoconnention ile bağlantı yapıyorum. 2 yan uygulamanın adoquerylerinin ise ana uygulama daki connection ile bağlanması gerekiyor. Ana uygulama sistem trayda çalışacak connectionlar sağlanacak. yan uygulamalar ise istenildiği zaman çalıştıralacak ve ana uygulama üzerinden veritabanına bağlanacak. Bu konuda çözüm önerisi sunarsanız çok sevinirim. Herkese iyi çalışmalar dilerim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

Merhaba...

- Tanımınız direkt 'Multitier' çağrıştırıyor. Yani veritabanına erişen sadece (1) sunucu ile bu sunucu aracılığıyla elde edilen veriye erişecek (n) adet client olarak anladım.
- (n) adet client her biri sunucu yazılımdan belli bir SQL sorgulamasını isteyecek, sunucu bizzat proxy sunucu olarak bu talebi yerine getirecek ve bulduğu sonucu bizatihi kendisi client'a yollayacak. Böylece Client'lar asla direkt olarak veritabanı ile ilişkiye girmeyecek. Doğru mudur ?

Aşağıda yazacaklarım bu anladığım sorunsala çözüm niteliğinde bir öneridir.

- Vaktim varken, sistemi anlamanız için bir giriş seviyesinde bir tanımlama ve basit bir proje ile de örnekleme yapmaya çalışayım... :idea:

1. Formunuza bir adet 'Remote Data Module' eklemeli, veritabanınıza erişim altyapınızı oluşturmalı, windows'a register etmelisiniz.
2. Client projelerde ise bu register edilene erişmek için DCOMConnection tanımlayıp ClientDataSet ile, dilerseniz aynı bilgisayardan dilerseniz ağdaki başka bir bilgisayardan aktif sunucudaki açık SQL sorgusunu doğruca çekebilirsiniz.
3. Geriye Client'lerden yapılacak sorguların tasarımı kalıyor. Çünkü ana bilgisayarda normalde sorgu sonucu ne varsa onu çekersiniz, değişiklik yapar geriye ApplyUpdates yaparsınız vs. Bu nedenle her client için bağımsız birer instance açmak gerekecektir.
- Client sayınızı belirleyip ona göre bir tasarım yaparsanız çok faydalı olur. SQL sorgularını transfer etmek için örnekte ifade ettiğim şekilde SUNUCU projenizde [poAllowCommandText] özelliğini DataSetProvider1.Options'dan aktifleştirmek unutulmamalıdır. Sunucu tarafından sorgu yaptırılır sonra Client app.lerin bu sonucu çekmesini sağlarsınız.

- Şimdi size küçük bir örnek ile ifade edeyim.
- Eklenen bilşen ayarlarına birşey yazmanıza gerek yok, aşağıda her formun Create eventinde buralara ne yazılacaksa belirttim.

// Şimdi Server Projede Yapılacaklar... ///
// Forma Bir Şey Eklemenize Lüzum Yok...
Sadece proje dizinine de elinizdeki örnek bir MSAccess mdb veritabanı dosyası koyun.

- Şimdi "File / New / Other / Multitier" başlığına gelin oradan bir adet "Remote Data Module" ekleyin.
- Eklerken sizden buna bir isim vermenizi isteyecektir. Bu ismi unutmayın ben örnek için 'BizimUzakBaglanti' ismini vereyim. Bu ismi verince Wizard size önce SunucuProjesi_TLB isminde (projemizin adı "SunucuProjesi.dpr") projenin adıyla ilintili bir unit oluşturup proje dizinine koyacaktır. Ayrıca verdiğimiz isim ile de bir CLASS oluşturup bunu yeni bir unit olarak ( örnekte unit2.pas ) olarak oluşturur.

* Yeni oluşturulan RemoteDataModule formuna aşağıdakileri ekleyin...
- DatasetProvider
- AdoConnection
- AdoQuery

- RemoteDataModule'in OnCreate eventine aşağıdaki gibi bir satır ekleyin.

Kod: Tümünü seç

procedure TBizimUzakBaglanti.RemoteDataModuleCreate(Sender: TObject);
begin
  AdoConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='
  + ExtractFilePath(Application.Exename) + 'database.mdb'; // Application.Exename için Uses'a FORMS ekleyin...
  AdoConnection1.LoginPrompt      := False;
  ADOQuery1.Connection            := ADOConnection1;
  AdoQuery1.SQL.Text              := 'SELECT * FROM tablo';
  // AdoQuery1'i Active etmeye gerek yok, ClientDataSet open olunca burası active olacak...
  DataSetProvider1.DataSet        := ADOQuery1;
  DataSetProvider1.Options        := [poAllowCommandText]; // bu satır sayesinde Client'den SQL text yollayıp cevabını alabiliyoruz...
end;
- işlem tamam gibi ama bir adım daha gerekecek. Şu haliyle çalışır ancak sunucu gibi davranmaz...

- Beklenen adım; Windows'a register etme vaktinin geldiğidir...
- Delphi IDE'deki menüden Run başlığı altında Register ActiveX Server yazar onu çalıştırın. "Successfylly Registered" mesajını alınca şimdi sunucunuz hazır...
- Artık 'localhost' olarak bu bilgisayardan veya bu bilgisayarın IP adresiyle erişeceğiniz diğer bilgisayardan 'SunucuProjesi.BizimUzakBaglanti' tanımı ile bu veritabanına erişiminiz açılmıştır.

// Şimdi Client Projeye geçelim... ///
// Forma aşağıdakileri ekleyin.
- DCOMConnection
- ClientDataSet
- DataSource
- DBGrid

Benzer bir yapı görüyoruz; AdoConnection yerine DCOMConnection, AdoQuery yerine ise ClientDataSet koyduk. Fark bunlar...
Formun OnCreate olayına aşağıdakileri yazın.

Kod: Tümünü seç

procedure TForm1.FormCreate(Sender: TObject);
begin
  DCOMConnection1.ComputerName := 'localhost';
  DCOMConnection1.ServerName   := 'SunucuProjesi.BizimUzakBaglanti';
  DCOMConnection1.Connected    := True;

  ClientDataSet1.RemoteServer  := DCOMConnection1;
  ClientDataSet1.ProviderName  := 'DataSetProvider1';
  DataSource1.DataSet          := ClientDataSet1;
  DBGrid1.DataSource           := DataSource1;
end;
Şu haliyle basit bir kurulum hazırladık... Bağlantı kurmak için bir button ekleyip aşağıdaki gibi yapın...

Kod: Tümünü seç

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  // SQL cümlemizi yollayalım...
  ClientDataSet1.CommandText := 'SELECT alan1, alan2 FROM Tablo';
  ClientDataSet1.Open;
end;
Buraya kadar basitçe sistemi anlamanız için bir giriş seviyesi tanım hazırladık...
Başarılar. :bravo:
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

sayın mrmarman ilginizden ve yardımınızdan dolayı çok teşekkür ederim. Deneyip tekrar forumda paylaşacağım. İyi çalışmalar
En son pasa_yasar tarafından 01 Kas 2013 11:35 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
Battosai
Üye
Mesajlar: 1316
Kayıt: 01 Eki 2007 12:02
Konum: Ankara

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen Battosai »

@mrmarman makale bölümüne yakışır çok güzel bir anlatım. Bu konu ile alakalı bilgisi olan pek yok denk gelenler için çok iyi bir başlangıç yazısı. Teşekkürler.
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

Denedim fakat run activex register ederken "Exception EOlesSysError in module NoteServer.ex at 000676D9 OLE kayıt defterine erişme hatası" şeklinde hata veriyor. çözüm öneriniz veya örnek demo uygulamanız varmı. İnternette araştırdım çok bişey bulamadım
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

Merhaba

UAC (kullanıcı hesabı denetimi) yüzündendir.

Hata mesajından anladığım Registry kaydına erişemediği şeklinde.

Delphi'yi sağ mause tıklayıp "Yönetici Olarak Çalıştır" deyin sonra tekrar deneyin.
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

Teşekkür ederim bağlantıyı gördü.

İki sorun var bu konuda gösterdi.

a. Bağlantı sağlar iken "Sunucu çalıştırması başarısız" şeklinde hata veriyor.
b. Her windows başladığında delphiyi açıp register etmem gerekiyor. uygulamayı windowsta başlatıp otomatik register edip başlatma yöntemi nedir acaba.

paylaşımlarınız için teşekkür ederim
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

Merhaba..

- Telefondan sorunuzu gördüm ancak resimlerle cevap vermek için cevap yazamadım.

-
@pasa_yasar yazdı:Her windows başladığında delphiyi açıp register etmem gerekiyor.
demişsiniz.

- Windows her başlatıldığında yeniden register edilmesine gerek yoktur. Normalde Windows tarafından hatırlanan bir özelliktir.

- Sadece projenin yerini değiştirirsen sorun olur, çünkü istemci (client) proje çalışınca sunucu o esnada çalışıyor olması, çalışmıyorsa erişim gerçekleşemeyeceğinden talep geldiği anda windows tarafından kendiliğinden çalıştırılması sağlanır.

- Yani client erişim istediği anda sunucu projen de kendiliğinden çalıştırılır.

:arrow: Projenden register olayı için de; ürettiğin EXE dosyasına /regserver parametre vererek register edebilirsin. (Bunu sorduğun iyi oldu önceki cevapta yazmayı unutmuşum..)

Örnek :
Projeni olması gereken Path'e kopyaladıktan sonra şunu yaz.

Kod: Tümünü seç

SunucuProjesi.exe /regserver
Bu komut sadece register edecektir.

- Oluşumu anlatayım. Windows'a bir kere Register ederseniz, sunucu programın yerini de register ediyorsunuz. Çünkü Client çalışınca ve bağlantı kurunca server projesi de kapalı ise kendiliğinden açılır. Muhtemelen yine yetkilendirmelere takıldınız.

- Başlat / Çalıştır deyince yazacağınız DCOMCNFG ile açılan pencereden Register sonucunu aşağıdaki gibi gözlemleyebilirsiniz.

Resim

- Yetkilendirme deyince üç tip yetkilendirme var.
Resim

- Buradaki başlıklar zaten kendini ifade ediyor.

Başarılar.
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

DCOMCNFG ile bileşen hizmetlerini çalıştırdığımda server çalışıyor görünüyor. Fakat clientten bağlandığımda Sunucu çalıştırma başarısız hatasını veriyor. Hata detayları aşağıdaki gibi

Kod: Tümünü seç

[2004474C]{rtl100.bpl  } ComObj.OleError (Line 1269, "common\ComObj.pas" + 1) + $11
[2004475B]{rtl100.bpl  } ComObj.OleCheck (Line 1276, "common\ComObj.pas" + 0) + $7
[20044C50]{rtl100.bpl  } ComObj.CreateRemoteComObject (Line 1403, "common\ComObj.pas" + 20) + $17
[0C403902]{dsnapcon100.bpl} MConnect.TDCOMConnection.DoConnect (Line 520, "MConnect.pas" + 15) + $27
[203A0C75]{dbrtl100.bpl} DB.TCustomConnection.SetConnected (Line 2627, "DB.pas" + 7) + $7
[0C4033EA]{dsnapcon100.bpl} MConnect.TDispatchConnection.SetConnected (Line 434, "MConnect.pas" + 9) + $6
[0C40366B]{dsnapcon100.bpl} MConnect.TCOMConnection.SetConnected (Line 475, "MConnect.pas" + 5) + $4
[2002AE7E]{rtl100.bpl  } TypInfo.SetOrdProp (Line 1316, "common\TypInfo.pas" + 27) + $0
[20D29FD6]{designide100.bpl} DesignEditors.TPropertyEditor.SetOrdValue (Line 841, "DesignEditors.pas" + 2) + $E
[20D2B073]{designide100.bpl} DesignEditors.TEnumProperty.SetValue (Line 1401, "DesignEditors.pas" + 5) + $4
[20D29C8D]{designide100.bpl} DesignEditors.TPropertyEditor.Edit (Line 671, "DesignEditors.pas" + 11) + $14
[20AB55C6]{coreide100.bpl} PropInsp.TPropertyInspector.PropListEditDblClick (Line 855, "PropInsp.pas" + 20) + $5
[20E0ED7D]{vclide100.bpl} IDEInspListBox.TInspListBox.DoEditDblClick (Line 967, "ideinsplistbox.pas" + 2) + $A
[20E10602]{vclide100.bpl} IDEInspListBox.TInspListBox.EditDblClick (Line 1538, "ideinsplistbox.pas" + 0) + $2
[2013CA49]{vcl100.bpl  } Controls.TControl.DblClick (Line 5234, "Controls.pas" + 1) + $14
[2013CBAC]{vcl100.bpl  } Controls.TControl.WMLButtonDblClk (Line 5275, "Controls.pas" + 4) + $C
[2013C527]{vcl100.bpl  } Controls.TControl.WndProc (Line 5146, "Controls.pas" + 83) + $6
[201406A7]{vcl100.bpl  } Controls.TWinControl.WndProc (Line 7304, "Controls.pas" + 111) + $6
[20140158]{vcl100.bpl  } Controls.TWinControl.IsControlMouseMsg (Line 7176, "Controls.pas" + 9) + $25
[201406A7]{vcl100.bpl  } Controls.TWinControl.WndProc (Line 7304, "Controls.pas" + 111) + $6
[20E0DF4B]{vclide100.bpl} IDEInspListBox.TPropInspEdit.WndProc (Line 430, "ideinsplistbox.pas" + 7) + $4
[2013FDD0]{vcl100.bpl  } Controls.TWinControl.MainWndProc (Line 7073, "Controls.pas" + 3) + $6
[20040E4C]{rtl100.bpl  } Classes.StdWndProc (Line 11583, "common\Classes.pas" + 8) + $0
[03B85275]{DelphiSpeedUp105.dll} SystemOptimize.DMTSearch (Line 198, "SystemOptimize.pas" + 4) + $7
[201625E8]{vcl100.bpl  } Forms.TApplication.ProcessMessage (Line 8103, "Forms.pas" + 21) + $1
[2016262A]{vcl100.bpl  } Forms.TApplication.HandleMessage (Line 8124, "Forms.pas" + 1) + $4
[2016291F]{vcl100.bpl  } Forms.TApplication.Run (Line 8223, "Forms.pas" + 20) + $3
(00003312){IDEFixPack.dll} [07534312]
[0042297A]{bds.exe     } bds.bds (Line 195, "" + 7) + $7
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

1. Client aynı bilgisayarda mı ?
2. farklı bilgisayarda ise Bilgisayarın FireWall'ı gerekli yetki geçişine açık mı ?
3. Resimde gösterdiğim uzaktan erişim yetkilendirmelerinde kullanıcı eklenmesi işlemini gerçekleştirdiniz mi ?

Bunlara cevap lütfen...
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

- client aynı bilgisayarda, güvenlik duvarı ve antivirüsü kontrol ettim ve her ihtimale karşı ekledim.
- resimdeki gibi uzaktan erişim yetkilendirmesi ile tüm kullanıcılara yetki verdim yine çalışmadı. Acaba göremediğim nereler var. Ufak ayar gereken birşey var diye tahmin ediyrum ama bulamıyorum
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

Merhaba.

- Sana bir proje hazırladım. İçine de bir veritabanı koydum. Bu linkten indirebilirsin.

- Yapacağın işlem Sunucu klasöründeki exe dosyasını aşağıdaki şekilde register edeceksin.

Kod: Tümünü seç

SunucuProjesi.exe /regserver
- Sonra client klasöründeki programı çalıştır bakalım bağlantı sağlayacak mı ?

Sonuç şöyle olmalı.
Resim
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

Mrb sorun çözüldü. Sanırım server uygulamasındaki class hariç tüm formları sildiğim için olmuş. Boş form ekleyip çalıştırınca çalıştı. Yardımlarınızdan dolayı size çok çok teşekkür ederim. Umarım birgün karşılaşır ve bire bir sohbet etme imkanı bulurum. İyi çalışmalar
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen mrmarman »

Çok memnun oldum.. :)
Karşılaşmak ümidiyle, kolaylıklar dilerim. :bravo:
Resim
Resim ....Resim
Kullanıcı avatarı
pasa_yasar
Üye
Mesajlar: 570
Kayıt: 07 Haz 2004 12:35

Re: Bağlantıyı dışarıdan almak

Mesaj gönderen pasa_yasar »

Tekrar bi soru sorabilirmiyim serverdaki database dışındaki herhangi bir nesneye client form üzerinden ulaşma imkanı var mı acaba. Atıyorum bir edit veya görsel olmayan bir dialog (resim açma veya dosya açmak gibi) türü nesnelere ulaşabilirmiyiz
Cevapla