Yazılımın ilk 250 günü - Part 18

12 dk okuma

171. Gün

Bugün front end konusunda en çok kullanmam gereken işlevleri (basit bir mesajlaşma uygulaması üzerine) yazdım. Hala en basit seviyede ama socket.io kullanarak anlık iki yönlü iletişimi sağlamam için gerekli front end kısmını içeriyor. Yarın ve bu haftanın geri kalanında sunucu ve client arasındaki iletişimi kurmaya çalışacağım. Amacım cumartesi websocket ile ilgili kısmı tamamlayabilmek. Bu akşam çalışıp eksik kalan kısımları tamamlamayı düşünüyordum fakat fırsat olmadı (Aile ve arkadaşlara vakit ayrılan vakit neticesinde). Onun dışında görevi yapabileceğimi düşünüyorum. Bu hafta isterlerimi tamamlayabilirsem çok sevineceğim kendi adıma. Yarın direkt socket.io’daki basit chat uygulaması örneğini kendi yazdığım sisteme uyarlayıp en temelden geliştirmeyi deneyeceğim. Sistemli bir şekilde ilerlediğimi düşünüyorum (Kendi çapımda bir sistemli ilerleyiş tabii ki de). Temel kısımları tamamlayıp eksiklerle karşılaştıkça da sorunları çözeceğimi düşünüyorum.

172. Gün

Front end tarafında en basit bir görünümü elde edebilmek cumartesi ve pazartesi günlerini almıştı. Bugün ise client’ta yazılan mesajı socket.io kullanarak sunucuya gönderme ve sunucunun da karşı bir cevap göndermesi işlendi. Evet basit bir mesajlaşma sağlanıyordu. Fakat bu mesajların text dosyası veya veritabanı gibi kalıcılığı olan bir yerde tutulması gerekliydi. Öğleden sonra tamamen bunun üzerine yoğunlaşıp neler yapabileceğimi düşündüm. İlk olarak, bu uygulamanın tutarlı işlediğini görebilmem için 3 tane kullanıcı olması gerekli. 3 kullanıcı ikili iletişim kurabilirler ya da beraber grup oluşturabilirler. 2 kişinin bir grupta olma ihtimalini açıkçası henüz hesaba katmadım ama bir grup olduğunda doğal olarak bir grup ismi de olacağı için, kişi sayısı yerine grup isminin varlığı ile bir grubun olup olmadığı anlaşılabilir. Bir tane bot kullanıcı olursa, kullanıcılar onunla iletişime geçebilir diye düşündüm. Bu bot’a şimdilik “Assistant” adını verdim. Bot kullanıcı, anketler oluşturup kullanıcılardan bu anketleri doldurmasını isteyebilir örneğin. Ya da kullanıcılar bir problemle karşılaştıklarında direkt ona iletebilir. Hatta kullanıcılar söylemeye çekindikleri ama dile getirmek istedikleri bir konuyu Assistant’a anonim olarak iletseydi nasıl olurdu diye de düşündüm.

Bugünün en çok düşündüren konusu veri yapılarının nasıl olması gerektiği idi. Şu aşamada bir veritabanı kullanmak yerine basitçe json/text dosyalarında veriler tutuluyor. Örneğin kullanıcı tablosu yerine “dbClient.json” dosyası, sohbet verileri tablosu yerine “chat.json”, session için de “session.json” dosyaları kullanılıyor. Bugün kullanıcı verileri ve sohbet verilerinin (sohbete katılan kişiler, sohbet id’si, sohbet içerikleri, sohbet tarihleri gibi) nasıl tutulabileceği üzerine düşünüldü. Bu iki farklı veri yapısının (ya da tablo/dosya) birbirleri ile bağlantısı, kullanıcıların id’si ve bulundukları sohbetlerin id’si üzerine olabilir diye düşünüldü ve bu şekilde oluşturuldu. Şu an var olan kullanıcı id’si ise oturum bilgilerinden elde edildi.

Ek olarak, bugün dinamik olarak mesajlar DOM metotları kullanılarak oluşturuldu. Ama mesajların oluşturulması yukarıda da belirtildiği gibi pek bir anlam ifade etmedi. Çünkü kullanıcı sayfayı yenilediğinde doğal olarak tüm mesajlar siliniyordu.

Yarın üzerine çalışmam gerektiğini düşündüğüm konular:
  1. Kullanıcının sohbet geçmişi varsa, geçmiş sohbetleri ile ilgili veriler socket.io aracılığı ile client’a aktarılacak. (Burada tüm mesajların aktarılması yerine son mesajın belirli karakter uzunluğundaki kısmı da aktarılabilir. Tıpkı skype’ın son sohbetler kısmında göründüğü gibi. Sonrasında kullanıcı o sohbete tıklarsa eğer tüm mesajlar yüklenebilir ya da yakın tarihteki mesajlar yüklenir ve kullanıcı çok daha eski mesajları görmek isterse, sonrasında veritabanından o mesajlarda çekilebilir. Şimdilik en optimize çözümü düşünmek yerine tüm mesajların veritabanından alındığı durumu yapacağımı düşünüyorum.)
  2. Kullanıcının sohbet geçmişi yoksa, Assistant ile bir sohbet başlatılacak. Önce veritabanına eklenip sonrasında client’a gösterilecek.
  3. Kullanıcının sohbet geçmişi varsa ve bu sohbetlerden herhangi birinde birden fazla katılımcı varsa eğer, bu sohbet grup olarak görülecek ve veriler client’a bu şekilde aktarılacak.
  4. Tüm bunlar gerçekleştirildiğinde ise, büyük ihtimalle front end tarafındaki eksiklikler göze çok çarpacak ve onlar basitçe düzeltilmeye çalışılacak.
  5. Önemli olan diğer bir konu ise henüz çok bilmediğim cache yapısı. Kullanıcının geçmiş mesajları kesinlikle bir veritabanından (ya da herhangi bir persistent storage-şimdi kullanılan text/json dosyası gibi) alınacak. Ama kullanıcının anlık olarak mesajlaşması durumunda bu veriler elbette veritabanına yazılacak fakat client tarafındaki veriler veritabanından alınarak değil, sadece sunucu tarafından işlenerek alınacak. Yeni bir mesaj yazıldığında, sunucu iki işlem yapar diye tahmin ediyorum. Birincisi bu yeni mesajı veritabanına asenkron olarak ekler. İkinci olarak da bu veriyi client’a teslim eder.
Açıkçası yapılacak çok fazla şey var. Problemleri en temel biçimde ele alıp ilerlemeye çalışıyorum. Her problem ve çözüm, yeni bir bakış açısı ve farklı alternatifleri sunuyor. Kullanıcı ya da bir grubun fotoğrafı olması ya da olmaması durumu, grup yöneticisi ve yetkileri, gruptan çıkmak ya da kullanıcıyı kaldırmak gibi çokça fazla konu ilgi bekliyor. Şu an bulunduğum konuma göre bu konular sonraki aşamalarda karşıma çıkacak daha detaylı kısımlar tabii ki. Bu yüzden, daha çok backend tarafını ilgilendiren problemleri yarın ele alacağım. Tamamlamaya çalışacağım.

173. Gün

Açıkçası istediğim şekilde ilerlediğimi hissediyorum. Tabii kendi isteklerim ne kadar önemli bilmesem de kendim yaptığım işten biraz da olsa tatmin oluyorum en azından. Bugün statik olarak var olan front end kısmına dinamik olarak verileri text dosyasından alarak eklemeye başladım. Elimden geldikçe değiştirilebilir, uyumlu, Bruce Lee’nin “Su gibi ol dostum, bulunduğun kabın şeklini al vs.” cümlesini özümseyerek, gelecek bir zamanda koda bakan bir kişinin düzeltebileceği bir kod yazmaya çalışıyorum. Hala daha OOP ile ilgili herhangi bir şey yazdığım kodda bulunmuyor aslında. Sadece orada anlatılmak istenenleri biraz da olsa kavradığımı düşündüğüm için aklımda “modüler bir kod yazmalısın Buğra” düşüncesi hakim. Henüz pek olmadı ama yapacağım diye umuyorum.

Biraz önce çok ufak bir şeyle karşılaştım ve onu öğrenmek bile epey keyifliydi. forEach’te döngünün istediğim yerde durmasını sağlamak için neler yapabilirim diye bakıyordum (kodun sonraki kısımlarını etkilemeden). every() fonksiyonu ile basitçe bu dediğimi yapabildiğimi öğrendim.

Bugün sadece text dosyasındaki, sohbet ile ilgili veriyi client’a sunma üzerine çalıştım olması gerektiği gibi. Bir html dosyasından backend ile iletişim kurmak için ajax/fetch gibi teknolojiler kullanmam gerekirdi. Fakat anlık mesajlaşmayı da socket.io ile oluşturduğum için, diğer kısımda da fetch/ajax yerine socket.io’yu tercih ettim. Ne kadar doğru henüz bilmiyorum. Henüz temel kısımları hâlâ bitmedi. Yarın veya en geç cuma gününe kadar grupların ve kişilerin olduğu, anlık mesajların da istenilen şekilde geldiği bir yapıyı kurmaya çalışacağım. Çok eksik var. Yapmam gereken daha çok şey var. İyi ki de var ve öğreniyorum. Çünkü aşırı zevkli (çarpıtılmış bir hedonizm olarak değil tabii ki bu zevk). Fakat zaman da su gibi akmaya devam ediyor.

5 kişinin yaptığı işi yapıyor muyum bilmiyorum ama ben hızlandığımı düşünüyorum eskiye nazaran. Ya da gösterdiklerinizi biraz da olsa pekiştirdim diye düşünüyorum (tamamen değil tabii ki de, en azından yüksek benzin fiyatları dolayısı ile benzini koklayan arabalar gibi kokusunu aldım sanırım birkaç şeyin: iyi bir kodun nasıl yazıldığını, kullanacağım teknolojileri, araçları. Mantıklı biriydim az çok fakat şimdi ufkumun daha da genişlediğini düşünüyorum. Yanlış yaptığım kısımlarda bir şeylerin yolunda gitmediğini hissediyorum birçok zaman. Bazen bilerek yanlış yapmaya da devam ediyorum çünkü iç sesimle yaptığım trade-off’ta yanlış yapıp sonra o kısmı düzeltmek ve farklı kısımları tamamlamak ağır basabiliyor). 5 kişinin yaptığı işi yapamam, çünkü beş kişi içerisinde ben de dahilim. Sıradan bi zekaya sahip ama kendini bu konuda geliştirmek isteyen basit bir insanım sadece. Benden neredeyse her konuda çok iyiler her zaman olacak. Ama ben de elimden geleni yapacağım.

174. Gün

Geçmişte yazılan mesajları, varolan sohbetleri, gerekli kullanıcı bilgilerini (fotoğraf, isim, durumu, vs.) alıp frontend kısmında yazabiliyorum. Anlık olarak yazılan mesajları da istediğim şekilde front end kısmında gösterebiliyorum. Fakat sistemi biraz yanlış kurguladığım için bazı çok ciddi problemlerim var. Nasıl çözeceğimi bildiğimi düşünüyorum. Problemim şu: Geçmiş mesajları rahatlıkla yazdırıyorum. Anlık yazılan mesajları text dosyasına asenkron olarak kaydediyorum ve bu esnada ekrana da yazdırıyorum. Fakat farklı bir sohbete girdiğimde bu anlık mesajlar kayboluyor. Sayfayı yenileyince geri geliyor tabii ki (Text dosyasından alarak gerçekleştiriyor). Kaybolma nedenini biliyorum çünkü kaybolmasını ben istemiştim ve ona göre birkaç satır kod yazmıştım. Çünkü eğer kaybolmazsa bu sefer tüm mesajlaşmalar tüm sohbetlerde karışık olarak bulunuyordu. Bir soruna karşı oluşturduğum bir çözüm, farklı bir yerde sorun yarattı. Bu yüzden mesajları chat id’sinin olduğu ana bir elemanda tutarak ve her yeni mesajı bu chat id’sinin bulunduğu kısma ekleyerek sorunu çözebilirim. Aktif olan sohbetin ilgili elemanı gösterip, diğer sohbetlerle ilgili kısmı saklarım. Her yeni mesajı veritabanına ekleyip, sonrasında oradan çekmemek için girdiğim yol bence yanlış değil ve uygulanabilir. Fakat sorunlarımı düzelteceğim. Bugün yapmak istediklerimi tamamladım fakat sonrasında oluşan sorunları henüz çözmedim.

Yarın yukarıda bahsettiğim çözümü uygulayıp sorunu giderirsem eğer, biraz daha spesifik kısımlara giriş yapacağım. O an sohbette bulunan kişilerden birinin mesaj yazması durumunu göstermeliyim. Mesajları düzenleme, silme gibi yetenekleri kullanıcıya sağlamalıyım. Sonrasında kullanıcının kendi statüsünü (müsait, meşgul, uzakta, offline gibi) değiştirmesini sağlamalıyım. Kullanıcı çıkış yaptığında ya da disconnected olduğunda offline’a geçmesini sağlamalıyım. Kullanıcıya yeni gelen mesajları da bildirimle göstermem gerekli.

Sağlam adımlarla ilerlemeye çalışıyorum.

175. Gün

Sadece bir kullanıcı SSO da var. Hayali kullanıcılar ve sohbet geçmişleri text dosyasından alınıyor. Olması gerektiği gibi front end kısmında eski ve yeni tüm mesajlar, sohbetler gösteriliyor. Bugün iki önemli problem çözüldü. Sizinde dediğiniz üzere socket’lerin hepsine yayın yapıldığı için farklı sekmelerden (ya da tarayıcıdan) aynı url’e erişince anormal davranışlar sergiliyordu uygulama. Bunu düzelttim. Sonrasında statü değiştirme durumlarını tamamladım (Hala birkaç eksiği var fakat daha önemli eksikleri tamamladıktan sonra geri döneceğim).

Okunmamış mesajların varlığını bildirmek, “is typing” ile sohbet sırasında mesaj yazan kişiyi göstermek, dosya gönderme gibi 3 kısım kaldı. İlk iki kısım için farklı kullanıcılardan mesaj gönderilmesi gerekiyor. Bunun için de SSO kısmına tekrar düzenleme yapmam gerekli çünkü kullanıcıların oturum açıp yazı yazabilmesi için SSO’da kayıtlarının olması gerekli ve SSO’dan client server’a gerekli kullanıcı verilerini transfer etmem gerekli. Yarın SSO kısmına uygulamadaki hataları gidermek için farklı kullanıcıların olma durumunu ekleyeceğim (olması gerektiği gibi. En başta yapmam gerekliydi fakat problemi değerlendirirken overengineering’e kaçmamalıyım derken fazla yüzeysel düşündüm sanırım). Bu düzenleme biraz zaman alabilir ama yapmak zorundayım. Ben karanlıkta olduğumu düşünmüyorum. Aksine ışığı görebiliyorum. Ulaşacağımı düşünüyorum. Bu hafta socket ile ilgili kısmı tamamlarım diye bekledim kendimden. Oysa ki tamamlayamadım hâlâ ama epey yol katettim. Tüm ana problemler bittikten sonra sesli ve görüntülü aramanın nasıl yapıldığını öğrenip uygulamak istiyorum mümkünse (Birçok uygulamada varsa neden mümkün olmasın tabii).

176. Gün

Bugün geçmişte yazdığım kodlarda düzeltmeler yaptım. Henüz bitmedi ve bu yüzden yarın akşam birkaç saat bakarım diye tahmin ediyorum. Birden fazla kullanıcının authentication bilgilerini SSO’da tutuyorum artık fakat client’ın session kısmında da düzenleme yapmam gerekli. Pazartesi tamamlarım diye tahmin ediyorum. Eğer tamamlarsam önemli bir problem kalmamış olacak diye düşünüyorum şu anlık.

177. Gün

SSO tarafını düzeltmiş olsam da; SSO’yu kullanan backend kısmında, session’ı da birden fazla session’I destekleyecek hâle getirmeliydim. Bugün bu durumu tamamlamaya çalıştım. Yanlış bir yolu takip ederek doğru bir şekilde çalışma izlenimi veren bir yapı kurdum. Fakat sonrasında bu yapıyı doğru bir şekilde çalışması için düzenlerken istemediğim sonuçları üretir hâle getirdim. Ama yarın tamamlayacağımı düşünüyorum o kısmı da. Eğer yarın tamamlarsam büyük bir iş yükü tamamlanmış olacak. İnanıyorum, olmak üzere.

178. Gün

Dün karşılaştığım ve çözemediğim problemi durgun bir zihinle bu sabah çözdüm. Sorun session’da birden fazla kullanıcının verisini tutmaktı. Şimdiye dek SSO tek kullanıcılı olduğu için client sunucu daki birden fazla kullanıcılı işlemleri statik olarak kendim oluşturup simüle ediyordum. Bu sabah bu problemi çözdüm. Sonrasında statü değiştirmedeki problemli yapıyı, “is typing” li kısmı doğru bir şekilde oluşturdum. Gün sonuna doğru bildirim konusuna baktım. Fakat şimdilik bildirimleri herhangi bir kalıcı dosyada tutmuyorum. Geçiçi olarak sadece online olan kullanıcılar o anda gelen bildirimleri görebiliyorlar. Bu konuya sonra tekrar döneceğim çünkü şimdilik önem sırası başka bir problemde: socket.io kullanarak dosya yüklemekte sıra. Doküman, fotoğraf, video, ve ses dosyalarını sunucuya gönderip kalıcı bir klasörde kaydetmeliyim. Front end kısmında da client’a bu dosyaları elbette sağlamalıyım. Dosya yükleme işlemi için 2 farklı node modülü ile sıkça karşılaştım. Ya kendim tamamen oluşturacağım ya da bu modüllerden birini kullanmayı düşünüyorum. Önce 3. parti herhangi bir modül kullanmadan deneyeceğim.

Tabii eşyanın tabiatı gereği problemler bitmemekte ve bu problemlere her zaman bir çözüm bulunuyor.

179. Gün

Bugün dosya yükleme konusuna girdim. Başta zor olduğunu sanmıştım fakat araştırınca kolay olduğunu anladım. Sadece biraz uğraştırıyor. Şimdiye dek gönderilen mesajlar sadece text olarak kullanıcıya gösteriliyordu. Fotoğraf, video, doküman (pdf,doc uzantılı), ses dosyalarını nasıl göndereceğimi, kaydedeceğimi, kullanıcıya göstereceğimi düşünüp kurgulamamıştım. Bugün o kısma başladım.

Anlık olarak dosyayı sunucuya gönderme ve ilgili sohbete dosyayı iletme işlemi tamamlandı. Sadece farklı dosya türleri için farklı durumları biraz daha düzenlemem gerekiyor. Henüz sohbet geçmişine gönderilen dosya ile ilgili kısmı eklemedim. Yarın bu konulardaki eksiklerimi tamamlayacağım.

Yarın büyük bir kısmını bitiririm diye tahmin ediyorum. Sorun şu: o kadar OOP çalışmama rağmen hala daha o bilgileri hiç kullanmıyorum (Mantıksal olarak modülaritesini yüksek tutmaya çalıştığımı düşünsem de bu çok yetersiz). Sanırım sonrasında kodu düzenleyeceğim. Proje başlangıcında diyagramları çıkarıp ona göre hareket etmeliydim diye düşünüyorum. Olsun, bu da benim için yeni bir deneyim ve kazanım oldu.

180. Gün

Toplam 180 iş gününe ulaşıldı. Toplam 7 ay tamamlandı (7 ay – 53 dakika ). Bugün socket.io ile yaklaşık 10-15 farklı türe (mime types) sahip olabilecek dosya local bir klasöre kaydedilip, kaydederken de aynı zamanda ilgili sohbetteki kişilere dosya iletildi. Uygulama açılırken geçmiş sohbet bilgilerinde de gönderilen dosyalar ile ilgili veriyi de tutmak gerekli elbette. Bu akşam o kısma başlandı. Yarın öğle yemeğine kadar bitirmek hedefleniyor. Aslında mantığı çok basit fakat uygulaması biraz zaman alacak. Hatalı yerler, eksikler hala çok var düşününce. Bildirim kısmı tamamlanmadı, sohbetler statik olarak eklendi (Şu aşamada tüm kullanıcılara eğer sohbetleri yoksa Assistant ile default olarak sohbet açıldı sadece). Yarın, geçmişte yüklenen dosyaları da kullanıcıya göstermek için gerekli çalışma yapılacak. Sonrasında mikrofon kullanılarak ses verisi kaydedip karşıdaki kullanıcıya nasıl gönderilir o konu araştırılacak. Yapılacak. Sonrasında ise canlı olarak sesli ve görüntülü konuşma sisteme eklenmeye çalışılacak. Hayaller Paris gibi dursa da projenin istenen şekilde (özelleştirilmiş Skype gibi) tamamlanacağı tahmin edilmektedir.

Bugün zip,rar,pdf gibi türlere sahip dokümanlar ile ses ve video dosyaları sisteme yüklendi. Yüklenebildi. Client’a da canlı olarak iletildi ve client doküman olarak sunulan dosyaları indirebildi. Fotoğraf, video, ses dosyalarını ise front-end kısmında açıp görüntüleyebildi ve ayrıca indirebildi. Bugün yaşanan bir sorun vardı. Socket.io default olarak maksimum 1Mb veri gönderilmesine izin veriyordu. Fazlasını göndermek istersek bağlantıyı kapatıp tekrar açıyordu hiçbir şey yaşanmamış gibi.

Gönderilecek dosyanın sahip olabileceği maksimum boyutu için bir seçenek socket.io dokümantasyonunda bulundu ve gönderilebilecek dosyanın maksimum boyutu 100 Mb yapıldı şu an için. Bu durum nasıl bir soruna yol açabilir henüz bilinmiyor (bilmiyorum). Veriyi demetler (chunks) şeklinde göndermek düşünüldü başlangıçta fakat daha zahmetli bir yol gibi göründüğü için bu kısayol tercih edildi.

Bence oluyor. Düzen ile beraber kaos da geliyor gibi hissediyorum. Elimden geldiğince düzene sokacağım.