Gerçek Zamanlı Programlamanın Zorlukları - Bölüm 1

Son zamanlarda çalıştığım şirketimle beraber içinde bulunduğum bir projede gerçek zamanlı çalışması gereken bir sistemin Frontend kısmını yeniden tasarladık.

Bununla beraber sistemin gerekli bileşenleri de arka planda RESTFUL çalışabilecek biçimde yeni bir API oluşturmamız gerekti.

Sistemimiz eskiden frontend kısmında jQuery kullanıyordu ve verileri gerçek zamanlı tutmak için long-polling teknolojisini kullanıyordu.

Yazdığımız yeni sistem ile beraber Frontend Framework olarak Google'ın geliştirmiş olduğu AngularJs'in 1.5 versiyonunu kullandık. Eski long-polling yapımızı ise Socket.IO ile beraber tamamıyla WebSocket uyumlu çalışmasını sağladık.

Projeyi AngularJs'e geçirmek özellikle AngularJs'in 2 way binding yapısından dolayı projenin Frontend kısmını özellikle maintenance açısından çok kolaylaştırdı.

Long-polling yerine Websocket tercih etmemiz ise özellikle sistem kaynaklarının tüketimini ciddi oranda düşürdü.

Yaptığımız değişikliğin buna nasıl sebep olduğunu anlayabilmek için öncelikle TCP (Transmission Control Protocol)'un nasıl çalıştığını anlamamız gerekiyor keza bu HTTP, HTTPS protokellerinin ve Websocketlerin temelini oluşturuyor.

Öncelikle istek yapan taraf örnek olarak internet tarayıcısına https://batikansenemoglu.com yazıyor bu noktada tarayıcı ilk olarak DNS sorgusu yapıyor ve batikansenemoglu.com'a karşılık gelen IP adresini buluyor örnek olarak 52.58.45.122 ardından standart HTTPS portu olan 443 portunu kullanarak yukarıdaki diyagramda bulunan connect() kısmına geliyor ve 52.58.45.122:443 ip adresini ve portunu kullanarak bağlantı kurmak istiyor ve makineye SYN (Synchronization) mesajı gönderiyor. Batıkan arkadaşımızın orada bulunan Amazon Elastic Route Balancing'i 443 portunu dinliyor ki bu noktada yukarıdaki diyagramın listen bölümüne geliyor. Server bağlantıyı kabul ederse SYN-ACK (Synchronization - Acknowledgment) mesajını Initiator'a geri gönderiyor, bunu alan initiator yani isteği yapan size connect() fonksiyonundan Success code'u dönüyor ve tarayıcınız ACK mesajını sunucuya tekrar gönderiyor böylece bağlantı kurulmuş oluyor. 1

Long polling yapısı gereği sürekli olarak sunucuya HTTP Request'ler yapıyor, normal Polling'den farklı olarak bu Requestleri sadece sunucu tarafında farklı bir şeyler olduğunda yapıyor. Örnek olarak Redisten PUB-SUB bir mesaj dinliyoruz Subscribe olduğumuz yerden bir mesaj geldi ve bunu yansıtmamız gerekiyor mesajı gönderiyoruz ve bağlantıyı kapatıyoruz Frontend istek bittiğinde gelen yeni mesajdaki işleri yapıyor ve tekrar HTTP Request yapıyor. Bu yukarıda yazılan işin her adımda tekrar yapılmasına sebep oluyor.

Fakat Websocket initiate ettiğimizde bu SYN > SYN-ACK > ACK aşaması 1 kere yapılıyor ve bağlantı Client - Server arasında açık kalıyor fakat bu da ilk yöntemin dışında bize bazı sorunlar getiriyor. Daha sonraki yazılarımda bunlara değineceğim.

  • Basit bir AngularJs uygulaması ve 2 way binding kavramı [ Bölüm 2 ]

  • AngularJs Socket.io client implementasyonu ve basit bir Node Socket.io serverı hazırlama [ Bölüm 3 ]

  • Laravel Framework'ünü kullanarak örnekler için basit bir REST API oluşturma. [ Bölüm 4 ]

  • HTTP Request - Response Life Cycle ve bu arada geçen zamanın hesaplanması [ Bölüm 5 ]

  • Server ve Client zamanını senkronize tutmak ve server ile sekronize geri sayaç yapmak [ Bölüm 6 ]

  • AngularJs ile istek aralarında kaybolan mesajları handle etmek için Priority Queue implementasyonu [ Bölüm 7 ]

  • AngularJs ile Socket Serverındaki kopmaları, Internet kopması gibi exceptional durumların handle edilmesi [ Bölüm 8 ]

Hepinize mutluluklar.

Batıkan Senemoğlu

Read more posts by this author.

İstanbul, Turkey https://batikansenemoglu.com