![]() |
|
Delphi ve Protocol Buffers - Baskı Önizleme +- Delphi Can (https://www.delphican.com) +-- Forum: Delphi (https://www.delphican.com/forumdisplay.php?fid=3) +--- Forum: Eğitim (https://www.delphican.com/forumdisplay.php?fid=19) +---- Forum: Makale (https://www.delphican.com/forumdisplay.php?fid=20) +---- Konu Başlığı: Delphi ve Protocol Buffers (/showthread.php?tid=3667) Sayfalar:
1
2
|
Delphi ve Protocol Buffers - SimaWB - 27-05-2019 Sık sık ihtiyaç duyduğumuz bir olaydır; yazdığımız iki uygulama arasında veri paylaşmak. İster iki uygulama da Delphi’de yazılmış olsun, ister farklı dillerde yazılmış olsun veri paylaşmak gerektiğinde verinin gönderiliş/alış şekli önemlidir. Bu gibi durumlarda verinin serileştirilmesi gerekir. Bunlardan en yaygın olanı XML ve JSON’dur. Ben başka bir alternatiften daha söz etmek istiyorum: Protocol Buffers.
Örneğin siz uygulamanızdan kişi bilgilerini başka uygulamaya göndermek istiyorsunuz. Bunu Delphi’deki bir class, bir record yada veri tabanından alınan bir kayıt gibi düşünebilirsiniz. Kişinin Id’si, ismi, email adresi ve telefon numara(lar)ı olduğunu düşünelim. Öncelikle bu veri yapısını Protobuf’ta tanımlamamız gerekir. Bunun için .proto uzantılı dosyalar kullanılır. Basit bir şeması vardır. Bizim örneğimiz için oluşturmamız gereken proto dosyası şöyle olabilir:
syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
string email = 3;
repeated string phonenumber = 4;
}
Görüldüğü gibi basit bir yapısı var, okunabilirliği çok kolay. Ama istenilirse çok detaylı veri yapıları oluşturulabilir. Detaylar için şuraya bakabilirsiniz: https://developers.google.com/protocol-buffers/docs/proto3Bir kişinin birden fazla telefon numarası olabileceği için phonenumber alanımızı repeated tanımladık. Her alanımızın sonunda tekil bir numara veriyoruz. Bu numaralar tekil olmalı ve daha sonra değiştirilmemeli. Bir message içinde başka bir message kullanabiliriz(nested). Bundan sonra yapılması gereken; bu mesajı hangi programlama dilinde kullanmak istiyorsak onun için derlemek. Google bunun için protoc.exe adında bir araç geliştirmiş. Protobuf’ın GitHub linkinden istediğiniz işletim sistemi için indirme yapabilirsiniz. Yukarıdaki örneğimizi person.proto adıyla kaydettiğimizi ve bu mesajları Java ve C# içinde kullanacağımızı varsayarsak: protoc.exe person.proto --java_out=DIR_PATH --csharp_out=DIR_PATH Bu komutu çalıştırdığımızda DIR_PATH klasörü altında hem Java hem de C# dosyalarının oluştuğu görülür. Yukarıda yazdığım gibi, desteklenen diller arasında maalesef Delphi yok (Artık bu tarz şeylere pek de şaşırmıyoruz)Delphi gibi resmi olarak desteklenmeyen diller için bir çok üçüncü parti çözümler üretilmiş ve onlar burada listelenmiştir. Ben Delphi için şunu kullanıyorum: https://github.com/kami-soft/ProtoBufGenerator Bu kütüphaneyi indirip ProtoBufGenerator.exe'yi kullanarak yukarıda protoc.exe’nin yaptığı işlemi Delphi için yapabiliriz. Yani proto dosyasından pas dosyası üretebiliriz. Yukarıdaki örnekten devam edecek olursak; person.proto'dan person.pas dosyasını elde ettik diyelim. Bu dosya içinde bizim Person mesajımız için TPerson sınıfının otomatik olarak oluşturulduğunu göreceksiniz.(Üstelik sınıf içinde yapılabilecek işlemler de otomatik olarak hazır )Basit bir sunucu-istemci örneği hazırladım. TCPClient ile mesajımız gönderip TCPServer ile okunuyor. ![]() Client’an mesaj gönderme kısmı; procedure TForm2.Button1Click(Sender: TObject); var Person: TPerson; MS: TMemoryStream; begin MS := TMemoryStream.Create; Person := TPerson.Create; try Person.id := 10; Person.name := 'DelphiCan'; Person.email := 'info@DelphiCan.com'; Person.phonenumberList.Add('05551234567'); Person.phonenumberList.Add('02167777777'); Person.phonenumberList.Add('7654321'); Person.SaveToStream(MS); IdTCPClient1.Socket.Write(MS, 0, True); finally Person.Free; MS.Free; end; end; Sunucuda mesajı alma kısmı: procedure TForm1. IdTCPServer1Execute(AContext: TIdContext); var aPerson: TPerson; MS: TMemoryStream; begin MS := TMemoryStream.Create; aPerson := TPerson.Create; try AContext.Connection.Socket.ReadStream(MS); aPerson.LoadFromStream(MS); // burada kişi bilgilerine erişebiliriz // aPerson.Id yada aPerson.name gibi // kişinin telefon numarası sayısı aPerson.phonenumberList.Count // kişinin ilk telefon numarası aPerson.phonenumberList[0] finally aPerson.Free; MS.Free; end; end; Görüldüğü gibi XML yada JSON parse’deki zahmetli işlerle uğraşmak zorunda kalmıyoruz. Her şey otomatik olarak oluşturulmuş sınıflarımız içerisinde mevcut. (Mesela yukaridaki örnekte telefon numarlarının tutulduğu phonenumberList otomatik oluşturulmuştur) Bu kullanımın güzelliği daha karmaşık mesajlar göndermek istediğinizde ortaya çıkacaktır. Proto dosyası içinde message içinde başka bir message (nested) kullanabilmeniz size çok büyük esneklik katacaktır. Protobuf’ın bir başka güzelliği ise; mesaj içinde değişiklik yaptığınızda eski versiyon mesajlarınızla da çalışmaya devam edebiliyorsunuz! Yeni bir alan ekleyebilirsiniz, var olanı silebilirsiniz vs. Özellikle farklı programlama dilleri arasında mesajlaşma gerektiğinde çok daha faydalı olduğunu görebilirsiniz. Karşı taraf hangi dili kullanıyorsa protoc.exe ile o dil için çıktı üretip karşı tarafa bunu veriyoruz. ProtoBuf böyle kısa bir makaleye sığdırılamayacak kadar güzel ve detaylı bir projedir. Ben sadece giriş mahiyetinde bilgilendirme yapmaya çalıştım. Umarım ilgilenen çıkar Örnek projenin kaynak kodlarını buradan indirebilirsiniz: https://yadi.sk/d/Xhq5K0MRhASeFw Delphi ve Protocol Buffers - shooterman - 27-05-2019 Hocam çok teşekkür ederim. harika bir anlatım olmuş. Elinize, emeğinize sağlık. Delphi ve Protocol Buffers - frmman - 27-05-2019 Teşekkürler faydalı ve güzel bir paylaşım için. Delphi ve Protocol Buffers - Tuğrul HELVACI - 27-05-2019 Ellerine sağlık güzel kardeşim. Mobil ortamdan bakıyorum, dolayısı ile detaylı bir inceleme şansım olmadı; lâkin bizim Delphi içinde tanımladığımız sınıfları Rest.Json unit’i içindeki TJson sınıfı ile serialize/deserialize etmek gözüme daha kolay göründü. Delphi ve Protocol Buffers - ismailkocacan - 27-05-2019 Elinize sağlık hocam, güzel anlatım. Cvp: Delphi ve Protocol Buffers - SimaWB - 27-05-2019 (27-05-2019, Saat: 19:33)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Ellerine sağlık güzel kardeşim. Mobil ortamdan bakıyorum, dolayısı ile detaylı bir inceleme şansım olmadı; lâkin bizim Delphi içinde tanımladığımız sınıfları Rest.Json unit’i içindeki TJson sınıfı ile serialize/deserialize etmek gözüme daha kolay göründü. Alışınca tadından yenmez ![]() Kolaylıktan ziyade ProtoBuf'ın asıl avantajı az yer kaplaması ve hızı. Sıradan bir proje için bunlar önem arz etmeyebilir ama Google Maps gibi bir projede bu yüzden ProtoBuf kullanılır. Yada giderek büyük bir hızla yayılan IOT dünyasında, büyük çapta bir projeye girildiğinde, sahada kullanılan binlerce cihazdan gelen/giden veri düşünüldüğünde harcanan bandwidth'in ne kadar önemli olduğu malumdur. Ben ProtoBuf'tan bahsettim, benden günah gitti
Delphi ve Protocol Buffers - klavye - 28-05-2019 Elinize saglik Cvp: Delphi ve Protocol Buffers - mkysoft - 09-12-2022 Makale icin ellerinize saglik. Gorebildigim kadariyla C#'da mevcut olan binary serilization mantigini kullaniyor. Belirttiginiz gibi tanim dosyasinin sonuna artan sirada yeni alan eklemek sorun olmaz. Ancak alan tipi degistiginde, araya alan eklendiginde sorun olacaktir, kullanirken dikkatli olmak lazim. Delphi ve Protocol Buffers - enigma - 09-12-2022 Bu sistem sadece LAN üzerinde mi çalışıyor yoksa internete bağlı iki kullanıcı arasında da geçerli mi ? D7'nin Demo programlarında NetChat diye bir program demosu vardı. Client Server bağlantısı üzerinden sadece LAN üzerinde Chat benzeri bir haberleşme sağlıyordu. Ona benziyor. Delphi ve Protocol Buffers - mkysoft - 09-12-2022 Konunun network iletisimi ile ilgisi yok. Konu objeleri veri olarak kaydedip tekrar olusturabilmekten ibaret. Veriyi ister LAN uzerinden gonderin ister eposta atin, ister db'ye kaydedin. |