NodeJS ve SocketIO ile Real-Time Grafik Uygulaması

Herkese merhaba, bu makalede yine ilgi çekici bir konu üzerinde anlatımlar ve örnekler paylaşacağım. Konu web dünyasında geniş yer bulan Online oyunlar, Canlı bahis siteleri, Canlı veri akışı gerçekleştiren finans ve borsa işlemleri, Chat siteleri gibi uygulamalarda yoğun olarak kullanılan Real-Time Data Transfer kavramı ile ilgili. Elbette bu saydığım örnekler web dünyası var olduğundan beri geliştirilegelen sistemler olduğu için bu kavramın da incelenmesi gereken hatırı sayılır bir geçmişi var.

Yazılan ilk uygulamalar Javascript ya da DHTML ile sayfanın belli aralıklarla yenilenmesi (refresh) ilkesine dayanıyordu ve veriler bu şekilde güncel tutulmaya çalışılıyordu bu çok ilkel ve sunucuları yoran bir yöntemdi ve bir an önce geliştirilmesi gerekiyordu.

Ardından AJAX (Asynchronous JavaScript and XML) teknolojisi geliştirildi. W3C tarafından XMLHttpRequest’in standartlaştırılması 2006 yılında gerçekleşse de tarihi 2000’li yıllara dayanan bu teknoloji web geliştiricilere yepyeni bir dünya sundu çünkü sayfayı yenilemeden ve diğer önemli bilgileri kaybetmeden sadece istenen verilerin güncellenmesini sağlayabiliyordu. Tüm işlemler Javascript ile gerçekleşiyordu ve haberleşme JSON formatında (XML destekleniyor) sağlanıyordu. Fakat bu teknoloji de asıl hedeften oldukça uzaktı çünkü Web’in temel mekanızması gereği iletişim tek taraflı yapılıyordu istemci sunucuya talep gönderiyor sunucu da istemciye cevap döndürüp bağlantıyı kapatıyordu dolayısıyla güncel verileri çekmek için sürekli sunucudan bilgi talep etmek gerekiyordu bu da tek bir bilgi için binlerce gereksiz request demekti.
Bu işleme PULL yöntemi denir. İstemcinin sunucudan bilgi talep etmesi manasına gelen bu kavramın birtakım sakıncaları var. Örneğin; Olayın meydana geldiği andan itibaren kullanıcıya bilgi gönderilmesi arasında bir miktar gecikme meydana gelmesi (Latency). Tek bir bilgi için defalarca ve boşu boşuna talep gönderilmesi. Kullanıcı sayısı arttığında sunucu yükü artması hedefimize uygun olmaması için yeterli sebeplerdir. Bunlara rağmen Ajax aktif olarak kullanılan ve gerektiği projelerde çok da işe yarayan bir teknolojidir.

Bu sebeple WebSocket teknolojisi geliştirilmiştir. WebSocket; TCP (Transmission Control Protocol) protokolü üzerinden çift yönlü veri haberleşmesi sağlayan veri transfer kanalıdır. Haziran 2008’de, Michael Carter tarafından, protokolün ilk versiyonu olan bir takım çalışma gerçekleştirilmiştir WebSocket protokolü IETF tarafından 2011 yılında RFC 6355 ile standart hale getirilmiş. Http protokolü ise tek taraflı veri transferi yapmak için tasarlanmıştır. 

WebSocket protokolü sürekli açık kalan bir bağlantı sayesinde çift taraflı veri transferi yapabilir ve sunucu da istemciye mesaj gönderebilir. Aşağıdaki grafik bu durumu güzek açıklamaktadır.

WebSocket protokolü Http’nin devamı veya gelişmiş bir versiyonu olarak görülmemellidir zira TCP tabanlı bağımsız bir protokoldür ve HTTP ile tek ilişkisi, HTTP sunucuları tarafından bir Upgrade isteği olarak yorumlanmasıdır.

Çalışma mantığını bu kadar açıkladıktan sonra uygulamaya geçelim. WebSocket protokolünü Asp.Net, PHP, Python, NodeJs  çeşitli platformlarda kullanabilirsiniz. Biz bu makalede Finans ve borsa işlemlerinde yoğun kullanılan Gerçek zamanlı grafik uygulaması yapacağız ve buna başlat ve durdur komutları ekleyerek bağlı tüm istemcilere komut gönderme örneği yapacağız bunun için bir NodeJS modülü olan SocketIO kütüphanesini kullanacağız. NodeJS kurulumu ve kullanımı için buradaki makalemi inceleyebilirsiniz. NodeJS’i kurduktan sonra komut satırına “npm install socketio” komutunu yazın ve socketio’yu bilgisayarınıza ya da sunucunuza kurun. Projeniz bittiğinde aşağıdaki gibi görünecek

Kurulum bittiğinde app.js isminde bir javascript dosyası oluşturun.SocketIO modülünü projenize aşağıdaki gibi require metoduyla ekleyoruz ve listen metoduyla 3000 portundan dinlemesini sağlıyoruz

var io = require('socket.io').listen(3000);

Aşağıdaki kullanım ile tüm nağlı client’lara belirlediğiniz bir event’i tetikleyerek broadcast mesaj gönderiyoruz.

io.sockets.emit("event name", {});

Aşağıdaki On() metoduyla parametre olarak verilen event tetiklendiğinde çalışacak fonksiyonu belirtiyoruz

io.sockets.on("event name", function() { });

App.js

var io = require('socket.io').listen(3000);
var inter = setInterval(datasender, 1000);

function datasender() {
    var x = (new Date()).getTime(),
        y = Math.random();
    io.sockets.emit("test", {
        x: x,
        y: y
    });
}

io.sockets.on('connection', function(socket) {

    socket.on('durdur', function(data) {
        clearInterval(inter);
    });
    socket.on('baslat', function(data) {
        inter = setInterval(datasender, 1000);
    });

});

Html Dosyanızı aşağıdaki gibi düzenleyin

<!DOCTYPE html>
<html>
   <head>
      <title></title>
      <meta http-equiv="Content-Type" content="text/html; charset=windows-1254" />
      <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
      <script src="http://localhost:3000/socket.io/socket.io.js"></script>
      <style type="text/css">
         body {
           margin: 0px;
           padding: 0px;
         }
         #container {
           width : 600px;
           height: 384px;
           margin: 8px auto;
         }
      </style>
   </head>
   <body>
      <div id="container"></div>
      <button id="btnbaslat">Başlat</button>
      <button id="btndurdur">Durdur</button>
      <script type="text/javascript" src="flotr2.min.js"></script>
      <script type="text/javascript">
         var socket = io.connect("http://localhost:3000");
         var chartdata = [];
         var graph;
         var container = document.getElementById('container');
         
         socket.on("test", function(data) {
         if(chartdata.length >= 10) chartdata.shift();
            chartdata.push([data.x, data.y]);

            graph = Flotr.draw(container, [ chartdata ], {
              yaxis : {
                max : 1,
                min : 0
              }
            });
         });
         
         $("#btnbaslat").click(function(){
           socket.emit("baslat");
         });
         $("#btndurdur").click(function(){
           socket.emit("durdur");
         });
      </script>
   </body>
</html>

Kaynak: http://www.jskoleji.com/201…

Umarım faydalı olmuştur.

Mustafa Tayyip Yetiş
Yazılım Geliştirme Uzmanı

 

4.0 Ort. (83% puan) - 1 oy

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir